我有一个类,它有自己的列表,因此可以用树结构表示。
我正在提取这些类的平面列表并想将其展开。
public class Group
{
public int ID {get;set;}
public int? ParentID {get;set;}
public List<Group> Children {get;set;}
}
我希望能够做到以下几点
List<Group> flatList = GetFlatList() //I CAN ALREADY DO THIS
List<Group> tree = BuildTree(flatList);
如果不明显,ParentID 与其父组的 ID 属性相关。
编辑
对于我返回列表而不是单个对象的原因有些困惑。
我正在构建一个包含项目列表的 UI 元素,每个元素都有一个子元素。所以初始列表没有根节点。到目前为止,似乎所有的解决方案都不起作用。
这意味着我本质上需要一个使用 Group 类的树型结构列表。
最佳答案
我不知道你为什么想要你的 BuildTree
方法返回 List<Group>
- 树需要有根节点,所以你应该期望它返回单个 Group
元素,而不是列表。
我会在 IEnumerable<Group>
上创建一个扩展方法:
public static class GroupEnumerable
{
public static IList<Group> BuildTree(this IEnumerable<Group> source)
{
var groups = source.GroupBy(i => i.ParentID);
var roots = groups.FirstOrDefault(g => g.Key.HasValue == false).ToList();
if (roots.Count > 0)
{
var dict = groups.Where(g => g.Key.HasValue).ToDictionary(g => g.Key.Value, g => g.ToList());
for (int i = 0; i < roots.Count; i++)
AddChildren(roots[i], dict);
}
return roots;
}
private static void AddChildren(Group node, IDictionary<int, List<Group>> source)
{
if (source.ContainsKey(node.ID))
{
node.Children = source[node.ID];
for (int i = 0; i < node.Children.Count; i++)
AddChildren(node.Children[i], source);
}
else
{
node.Children = new List<Group>();
}
}
}
用法
var flatList = new List<Group>() {
new Group() { ID = 1, ParentID = null }, // root node
new Group() { ID = 2, ParentID = 1 },
new Group() { ID = 3, ParentID = 1 },
new Group() { ID = 4, ParentID = 3 },
new Group() { ID = 5, ParentID = 4 },
new Group() { ID = 6, ParentID = 4 }
};
var tree = flatList.BuildTree();
关于c# - 通过递归检查父子关系构建树型列表C#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15867478/