C#-让孩子达到指定的深度

时间:2018-08-17 06:55:52

标签: c# linq asp.net-core

我有一个包含父子关系的列表,我想让子级达到定义的长度:

提供以下课程:

public class Item
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int ParentId { get; set; }
}

以下是列表:

var list = new List<Item>();
list.Add(new Item { Id = 1, Name = "Parent", ParentId = 0 });
list.Add(new Item { Id = 2, Name = "Child1", ParentId = 1 });
list.Add(new Item { Id = 3, Name = "Child2", ParentId = 1 });
list.Add(new Item { Id = 4, Name = "GrandChild1", ParentId = 2 });
list.Add(new Item { Id = 5, Name = "GrandChild2", ParentId = 2 });
list.Add(new Item { Id = 6, Name = "GrandChild3", ParentId = 3 });
list.Add(new Item { Id = 7, Name = "GrandChild4", ParentId = 3 });
list.Add(new Item { Id = 8, Name = "GrandGrandChild1", ParentId = 4 });
list.Add(new Item { Id = 9, Name = "GrandGrandChild2", ParentId = 5 });
list.Add(new Item { Id = 10, Name = "GrandGrandChild3", ParentId = 6 });
list.Add(new Item { Id = 11, Name = "GrandGrandChild4", ParentId = 7 });

现在,我希望如果我在URL中传递depth = 0,那么它将返回所有数据,但是如果我传递depth = 1,则它将返回如下字符串:

"Parent:Child1:GrandChild1:GrandGrandChild1"
"Parent:Child1:GrandChild2:GrandGrandChild2"

如果我通过depth = 2,那么:

"Parent:Child1:GrandChild1:GrandGrandChild1"

我尝试了以下代码:

public void Traverse(List<Item> list)
{
    var parentIds = list.Where(e => e.ParentId > 0).Select(e => e.ParentId).ToList();

    var bargs = list.Where(e => !parentIds.Contains(e.Id)).ToList();

    foreach (var item in bargs)
    {
        Traverse(list, item);
    }
}

private void Traverse(List<Item> items, Item item)
{
    var list = new List<Item> { item };

    int id = item.ParentId;

    while (true)
    {
        var found = items.Where(e => e.Id == id).FirstOrDefault();
        list.Insert(0, found);

        if(found.ParentId == 0) { break; }

        id = found.ParentId;
    }

    var str = string.Empty;
    foreach (var node in list)
    {
        str += node.Name;
        if(node != item) { str += ":"; }
    }

    Console.WriteLine(str);
}

现在此代码成功返回了所需的字符串,但是我不知道如何在“项目”中添加深度检查。深度可以为“ n”,因此如果不能,则无法添加。有帮助吗?

1 个答案:

答案 0 :(得分:1)

请参阅以下功能:

    /// <summary>
    /// Function to get the string representations of the hierarchy List
    /// </summary>
    /// <param name="Items">The hierarchical list of items</param>
    /// <param name="rootItem">The item whose children are to be traversed</param>
    /// <param name="depth">Depth to which the function should traverse. Passsing zero will make the function traverse throughout the heirarchy</param>
    /// <returns>List of string representing each hierarchy</returns>
    public List<string> GetChildren(List<Item> Items, Item rootItem, int depth)
    {
        List<string> ReturnList = new List<string>();

        TraverseChildren(Items, rootItem, depth, 1, ReturnList, rootItem.Name);

        return ReturnList;
    }

    private void TraverseChildren(List<Item> items, Item rootItem, int depth, int currentLevel, List<string> hierarchyList, string hierarchyString)
    {
        // Return If current level is higher than Depth
        // And depth is non-zero
        if (currentLevel > depth && depth !=0) { return; }

        Item[] Children = items.Where(x => x.ParentId == rootItem.Id).ToArray();

        foreach (Item itm in Children)
        {
            string currentItemHeirarchyString = string.Format("{0}:{1}", hierarchyString, itm.Name);
            hierarchyList.Add(currentItemHeirarchyString);

            TraverseChildren(items, itm, depth, currentLevel + 1, hierarchyList, currentItemHeirarchyString);
        }
    }

样品用量:

        // Get the item whose children to be traveresed
        Item RootItem = list.FirstOrDefault(x => x.Name == "Child1");
        GetChildren(list, RootItem, 1);

结果将是

Child1:GrandChild1
Child1:GrandChild2