您可以使用下面的擴展方法壓扁層次結構(見下文答案更新替代扁平化算法):
public static IEnumerable<T> Flatten<T>(
this IEnumerable<T> source, Func<T, IEnumerable<T>> childrenSelector)
{
foreach (var item in source)
{
yield return item;
var children = childrenSelector(item);
if (children == null)
continue;
foreach (var child in children.Flatten(childrenSelector))
yield return child;
}
}
我需要孩子選擇和遞歸得到孩子。然後將投射很簡單:
var result = nodes.Flatten(n => n.Children).Select(n => n.Id);
假定你有以下節點類:
public class Node
{
public Node(int id, params Node[] children)
{
Id = id;
if (children.Any())
Children = new List<Node>(children);
}
public int Id { get; set; }
public List<Node> Children { get; set; }
}
與樣品層次
然後:
List<Node> nodes = new List<Node> {
new Node(1),
new Node(2, new Node(3)),
new Node(4, new Node(5),
new Node(6, new Node(7)))
};
輸出將是:
1, 2, 3, 4, 5, 6, 7
UPDATE:您可以拼合層次不遞歸的使用情況(更好的性能):
public static IEnumerable<T> Flatten<T>(
this IEnumerable<T> source, Func<T, IEnumerable<T>> childrenSelector)
{
Queue<T> queue = new Queue<T>();
foreach (var item in source)
queue.Enqueue(item);
while (queue.Any())
{
T item = queue.Dequeue();
yield return item;
var children = childrenSelector(item);
if (children == null)
continue;
foreach (var child in children)
queue.Enqueue(child);
}
}
孩子節點的子類型? –
@SergeyBerezovskiy不,Node和Child是同一類型的。我更新了我的問題,使其更加清晰。 – Marcus
[使用LINQ搜索樹](http://stackoverflow.com/questions/7062882/searching-a-tree-using-linq)應該讓你知道該怎麼做。 – Dirk