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);
            }
        }
    }

它给了我一个简单的清单。期待您的建议。

C#通过递归获得层次列表

为了构建层次结构,您需要将结果存储在层次结构中,而不是平面列表中。您的递归方法需要重新设计:

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);
    }        
}

你必须确保每个父母/孩子的作业都在正确的地方完成,否则你会得到一个平面列表。

注意:我已经更改了这里的一些数据类型,以便像您所做的那样使用动态,但我确实建议创建一个强制类型来保存您想要的结构,而不是依赖于匿名类型