C#通过递归获得层次列表
本文关键字:层次 列表 递归 | 更新日期: 2023-09-27 18:25:07
在我的Azure表中,我有一个树状结构。我试图实现的是获得一个像这样的数据列表
var data = [{
item1 : {
name : "",
children : [] // list of children, if any children is a parent of other items get those
}
}]
我已经写了这个代码
List<dynamic> test = new List<dynamic>();
DisplayTree(NewMassType.GetAll().Where(e => e.ParentId == null), test);
public void DisplayTree(IEnumerable<NewMassType> elements, List<dynamic> test)
{
foreach (var element in elements)
{
test.Add(new
{
name = element.Name
});
var children = NewMassType.GetAll().Where(e => e.ParentId == element.Id);
if (children.Count() > 0)
{
DisplayTree(children,test);
}
}
}
它给了我一个简单的清单。期待您的建议。
为了构建层次结构,您需要将结果存储在层次结构中,而不是平面列表中。您的递归方法需要重新设计:
static List<dynamic> DisplayTree(IEnumerable<NewMassType> elements) {
var res = new List<dynamic>();
foreach (var element in elements) {
var children = DisplayTree(NewMassType.GetAll().Where(e => e.ParentId == element.Id)).ToArray();
if (children.Length != 0) {
res.Add(new {
name = element.Name
, children = children
})
} else {
res.Add(new {
name = element.Name
})
}
}
return res;
}
此代码和您的代码之间的关键区别在于,每次递归调用都会生成一个单独的列表,当列表不为空时,该列表会添加到匿名类型的对象中。
它给您一个平面列表的原因是因为您每次都会传入顶级集合。
DisplayTree(children,test);
它只是将子项附加到列表的末尾。您真正需要的是一种替代方法,它专门填充子级,而不是顶级。
List<dynamic> test = NewMassType.GetAll().Where(e => e.ParentId == null);
foreach (var element in test)
{
PopulateChildren(element);
}
// Somewhere down the line have a method
public void PopulateChildren(dynamic element)
{
var children = NewMassType.GetAll().Where(e => e.ParentId == element.Id);
element.children = children;
foreach (var child in element.children)
{
PopulateChildren(child);
}
}
你必须确保每个父母/孩子的作业都在正确的地方完成,否则你会得到一个平面列表。
注意:我已经更改了这里的一些数据类型,以便像您所做的那样使用动态,但我确实建议创建一个强制类型来保存您想要的结构,而不是依赖于匿名类型