获取对象和所有后代对象

时间:2013-10-10 11:43:52

标签: c#

如果我有以下列表

List<FlatObject> objects = new List<FlatObject>();

objects.Add(new FlatObject { ID = 1, ParentID = 0, Name = "January", Amount = 1000 });          
objects.Add(new FlatObject { ID = 2, ParentID = 0, Name = "February", Amount = 2000 });        
objects.Add(new FlatObject { ID = 3, ParentID = 0, Name = "March", Amount = 3000 });    
objects.Add(new FlatObject { ID = 4, ParentID = 0, Name = "April", Amount = 4000 });    
objects.Add(new FlatObject { ID = 5, ParentID = 0, Name = "May", Amount = 5000 });
objects.Add(new FlatObject { ID = 6, ParentID = 1, Name = "June", Amount = 6000 });
objects.Add(new FlatObject { ID = 7, ParentID = 1, Name = "July", Amount = 7000 });
objects.Add(new FlatObject { ID = 8, ParentID = 1, Name = "August", Amount = 8000 }); 
objects.Add(new FlatObject { ID = 9, ParentID = 2, Name = "September", Amount = 9000 }); 
objects.Add(new FlatObject { ID = 10, ParentID = 2, Name = "October", Amount = 10000 });
objects.Add(new FlatObject { ID = 11, ParentID = 2, Name = "November", Amount = 11000 });
objects.Add(new FlatObject { ID = 12, ParentID = 10, Name = "December", Amount = 12000 });
objects.Add(new FlatObject { ID = 13, ParentID = 10, Name = "January", Amount = 13000 }); 
objects.Add(new FlatObject { ID = 14, ParentID = 10, Name = "February", Amount = 14000 });
objects.Add(new FlatObject { ID = 15, ParentID = 3, Name = "March", Amount = 15000 });
objects.Add(new FlatObject { ID = 16, ParentID = 3, Name = "April", Amount = 16000 });
objects.Add(new FlatObject { ID = 17, ParentID = 3, Name = "May", Amount = 17000 });

有没有人知道如何编写一个返回对象列表及其所有递归子元素的函数?

例如,如果我输入id = 2的参数,我想回来

FlatObject { ID = 2, ParentID = 0, Name = "February", Amount = 2000 });     
FlatObject { ID = 9, ParentID = 2, Name = "September", Amount = 9000 });
FlatObject { ID = 10, ParentID = 2, Name = "October", Amount = 10000 });
FlatObject { ID = 11, ParentID = 2, Name = "November", Amount = 11000 });
FlatObject { ID = 12, ParentID = 10, Name = "December", Amount = 12000 });
FlatObject { ID = 13, ParentID = 10, Name = "January", Amount = 13000 });
FlatObject { ID = 14, ParentID = 10, Name = "February", Amount = 14000 });
列表中的

;

如果我回到孩子身边,我知道如何使用LINQ这样做,但如果我要找回孩子和后代,我就知道了。

3 个答案:

答案 0 :(得分:1)

您可以在高级别中使用递归函数,如下所示

private List<int> GetAllChildren(int parent)
{
    List<T> children = new List<T>();
    PopulateChildren(parent.ID, children);
    return children;
}

private void PopulateChildren(int parent, List<int> children)
{

    //look up immediate childs and pass each child to recursice method and add child to list
}

答案 1 :(得分:1)

假设ID始终是唯一的,非零父ID在集合中始终具有相应的对象,并且所有根对象都具有ParentID为零,您可以创建一个扩展方法,该方法可以从具有以下对象的对象中回答某个对象是子对象还是孙对象。某个ID:

public static bool HasAncestor(this FlatObject obj, IEnumerable<FlatObject> objs, int id)
{
    if (obj.ID == id)
       return true;
    if (obj.ParentID == 0)
       return false;
    return objs.Single(o => o.ID == obj.ParentID)  // Get parent
               .HasAncestor(objs, id);             // recurse
}

鉴于你也可以用另一种方式使用它,获取具有某个祖先的所有对象

public static IEnumerable<FlatObject> GetAllChildren(this FlatObject obj, IEnumerable<FlatObject> objs)
{
    return objs.Where(o => o.HasAncestor(objs, obj.ID));
}

答案 2 :(得分:0)

这是您的完整解决方案(已测试)。只需将FlatObjectExtention添加到您的解决方案中即可。

class Program
{
    static void Main(string[] args)
    {
        List<FlatObject> objects = new List<FlatObject>();

        objects.Add(new FlatObject { ID = 1, ParentID = 0, Name = "January", Amount = 1000 });
        objects.Add(new FlatObject { ID = 2, ParentID = 0, Name = "February", Amount = 2000 });
        objects.Add(new FlatObject { ID = 3, ParentID = 0, Name = "March", Amount = 3000 });
        objects.Add(new FlatObject { ID = 4, ParentID = 0, Name = "April", Amount = 4000 });
        objects.Add(new FlatObject { ID = 5, ParentID = 0, Name = "May", Amount = 5000 });
        objects.Add(new FlatObject { ID = 6, ParentID = 1, Name = "June", Amount = 6000 });
        objects.Add(new FlatObject { ID = 7, ParentID = 1, Name = "July", Amount = 7000 });
        objects.Add(new FlatObject { ID = 8, ParentID = 1, Name = "August", Amount = 8000 });
        objects.Add(new FlatObject { ID = 9, ParentID = 2, Name = "September", Amount = 9000 });
        objects.Add(new FlatObject { ID = 10, ParentID = 2, Name = "October", Amount = 10000 });
        objects.Add(new FlatObject { ID = 11, ParentID = 2, Name = "November", Amount = 11000 });
        objects.Add(new FlatObject { ID = 12, ParentID = 10, Name = "December", Amount = 12000 });
        objects.Add(new FlatObject { ID = 13, ParentID = 10, Name = "January", Amount = 13000 });
        objects.Add(new FlatObject { ID = 14, ParentID = 10, Name = "February", Amount = 14000 });
        objects.Add(new FlatObject { ID = 15, ParentID = 3, Name = "March", Amount = 15000 });
        objects.Add(new FlatObject { ID = 16, ParentID = 3, Name = "April", Amount = 16000 });
        objects.Add(new FlatObject { ID = 17, ParentID = 3, Name = "May", Amount = 17000 });

        objects.First(x=>x.ID==2).GetAllChildren(objects).ToList().ForEach(Console.WriteLine);

        Console.ReadKey();
    }
}

public class FlatObject
{
    public int ID { get; set; }
    public int ParentID { get; set; }
    public string Name { get; set; }
    public int Amount { get; set; }

    public override string ToString()
    {
        return string.Format("ID={0} ParentID={1} Name={2} Amount={3} ", ID, ParentID, Name, Amount);
    }
}

public static class FlatObjectExtention
{
    public static IList<FlatObject> GetAllChildren(this FlatObject flatObject, IList<FlatObject> allItems)
    {
        var allChildren = new List<FlatObject>();
        var children = allItems.Where(x => x.ParentID == flatObject.ID).ToList();
        allChildren.AddRange(children);

        foreach (var child in children)
        {
            allChildren.AddRange(child.GetAllChildren(allItems));
        }
        return allChildren;
    }
}