Większość przedstawionych tutaj odpowiedzi to sekwencje zstępujące w głąb lub zygzakowate. Na przykład zaczynając od poniższego drzewa:
1 2
/ \ / \
/ \ / \
/ \ / \
/ \ / \
11 12 21 22
/ \ / \ / \ / \
/ \ / \ / \ / \
111 112 121 122 211 212 221 222
Odpowiedź dasblinkenlight daje następującą spłaszczoną sekwencję:
111, 112, 121, 122, 11, 12, 211, 212, 221, 222, 21, 22, 1, 2
Konamiman za odpowiedź (która uogólnia Eric Lippert na odpowiedź ) produkuje ten spłaszczony sekwencję:
2, 22, 222, 221, 21, 212, 211, 1, 12, 122, 121, 11, 112, 111
Ivan Stoev za odpowiedź produkuje ten spłaszczony sekwencję:
1, 11, 111, 112, 12, 121, 122, 2, 21, 211, 212, 22, 221, 222
Jeśli interesuje Cię następująca sekwencja wszerz :
1, 2, 11, 12, 21, 22, 111, 112, 121, 122, 211, 212, 221, 222
... to jest rozwiązanie dla Ciebie:
public static IEnumerable<T> Flatten<T>(this IEnumerable<T> source,
Func<T, IEnumerable<T>> childrenSelector)
{
var queue = new Queue<T>(source);
while (queue.Count > 0)
{
var current = queue.Dequeue();
yield return current;
var children = childrenSelector(current);
if (children == null) continue;
foreach (var child in children) queue.Enqueue(child);
}
}
Różnica w implementacji polega w zasadzie na użyciu a Queue
zamiast a Stack
. Nie ma faktycznego sortowania.
Uwaga: ta implementacja jest daleka od optymalnej pod względem wydajności pamięci, ponieważ duży procent całkowitej liczby elementów zostanie zapisany w wewnętrznej kolejce podczas wyliczania. Stack
-oparte drzewa-przechodzenie są znacznie bardziej wydajne pod względem użycia pamięci niż Queue
implementacje oparte na -base.