2012-02-13 57 views
0

我想用打开的Generic T将对象的层次结构展平。使用递归和泛型删除层次结构中的选定节点

此链接Recursive List Flattening

展示了如何做到这一点隔空传递的IEnumerable。但我想扁平化一个传递对象T和

其属性子类以通用和递归方式。

U1.Children(U2,U3,U4) 
U2.Children(U9,U10) 
U3.Children(U11,U12) 
U4.Children(U20,U30) 

我传递给方法U1(选择的节点),我想这个平面列表:

U1,U2,U3,U4,U9,U10,U11,U12,U20,U30 

这有可能以某种方式在一个通用的方式?

回答

2

您可以定义接受取回孩子的函数的递归扩展方法:

public static IEnumerable<T> Flatten<T>(this T root, Func<T, IEnumerable<T>> getChildren) 
{ 
    IEnumerable<T> rootSingleton = new T[] { root }; 
    IEnumerable<T> children = getChildren(root); 
    IEnumerable<T> descendants = children.SelectMany(child => Flatten(child, getChildren)); 
    return rootSingleton.Concat(descendants); 
} 

然后,你可以使用它,像这样:

var flat = u1.Flatten(u => u.Children); 
0

如果您hierarcy只有一个级别深度您可以使用许多选择与工会

public IEnumerable<T> Flattern<T>(IEnumerable<T> input) where T : ISomeinterface { 
    return input.SelectMany(t=> t.Children).Union(input) 
} 

嗯,这代码不能编译UNESS你会用一些基类或接口具有Children属性约束它。编译器必须知道对象具有propertyl

+0

nah ...输入不能是一个IEnumerable 但T与儿童财产。看我的样品。 – Pascal 2012-02-13 20:14:08