我已经坚持这个问题几天了,并且会感谢一些想法或帮助解决它。 我有一组对象
public class Hierarchy
{
public Hierarchy(string iD, string name, int level, string parentID, string topParent)
{
ID = iD;
Name = name;
Level = level;
ParentID = parentID;
Children = new HashSet<Hierarchy>();
}
public string ID { get; set; }
public string Name{ get; set; }
public int Level { get; set; }
public string ParentID { get; set; }
public ICollection<Hierarchy> Children { get; set; }
}
Linq查询到我的实体的数据是:
ID Name Level ParentID
295152 name1 1 null
12345 child1 2 295152
54321 child2 2 295152
44444 child1a 3 12345
33333 child1b 3 12345
22222 child2a 3 54321
22221 child2b 3 54321
22002 child2c 3 54321
20001 child2a2 4 22222
20101 child2b2 4 22222
这些数据可能会扩展到未知的深度(我只显示4)。 最终,我会有一个Hierarchy对象,其中包含多个子对象的集合,而这些对象又可能包含多个子对象的集合......等等...... 总会只有一个顶级对象。
我正试图在这个项目中尽可能多地使用Linq。
这显然需要某种递归方法,但我被卡住了。任何想法或帮助将不胜感激。
TIA
答案 0 :(得分:4)
实际上,迭代解决方案可能要容易得多。以下是步骤:
看起来像这样:
Hierarchy CreateTree(IEnumerable<Hierarchy> Nodes)
{
var idToNode = Nodes.ToDictionary(n => n.ID, n => n);
Hierarchy root;
foreach (var n in Nodes)
{
if (n.ID == null)
{
if (root != null)
{
//there are multiple roots in the data
}
root = n;
continue;
}
Hierarchy parent;
if (!idToNode.TryGetValue(n.ID, parent))
{
//Parent doesn't exist, orphaned entry
}
parent.Children.Add(n);
}
if (root == null)
{
//There was no root element
}
return root;
}
您的数据格式存在几个明显可能的错误情况。由你来决定它们是什么。
通常,总会有迭代解决方案和递归解决方案。特定问题会改变哪一个更容易。
答案 1 :(得分:4)
你可以试试这个递归函数:
void PopulateChildren(Hierarchy root, ICollection<Hierarchy> source)
{
foreach (var hierarchy in source.Where(h => h.ParentID == root.ParentID))
{
root.Children.Add(hierarchy);
PopulateChildren(root, source);
}
}
您可以这样使用:
ICollection<Hierarchy> hierarchies = new List<Hierarchy>(); // source
// Get root
var root = hierarchies.Single(h => h.Level == 1);
// Populate children recursively
PopulateChildren(root, hierarchies);