Ci-dessous, le code d'Ivan Stoev avec la particularité d'indiquer l'index de chaque objet dans le chemin. Par exemple, recherchez "Item_120" :
Item_0--Item_00
Item_01
Item_1--Item_10
Item_11
Item_12--Item_120
retournerait l'élément et un tableau d'int [1,2,0]. Évidemment, le niveau d'imbrication est également disponible, comme la longueur du tableau.
public static IEnumerable<(T, int[])> Expand<T>(this IEnumerable<T> source, Func<T, IEnumerable<T>> getChildren) {
var stack = new Stack<IEnumerator<T>>();
var e = source.GetEnumerator();
List<int> indexes = new List<int>() { -1 };
try {
while (true) {
while (e.MoveNext()) {
var item = e.Current;
indexes[stack.Count]++;
yield return (item, indexes.Take(stack.Count + 1).ToArray());
var elements = getChildren(item);
if (elements == null) continue;
stack.Push(e);
e = elements.GetEnumerator();
if (indexes.Count == stack.Count)
indexes.Add(-1);
}
if (stack.Count == 0) break;
e.Dispose();
indexes[stack.Count] = -1;
e = stack.Pop();
}
} finally {
e.Dispose();
while (stack.Count != 0) stack.Pop().Dispose();
}
}
1 votes
Dans quel ordre voulez-vous que la liste soit aplatie ?
1 votes
Quand les nœuds cessent-ils d'avoir des nœuds enfants ? Je suppose que c'est quand
Elements
est nulle ou vide ?0 votes
Pourrait faire double emploi avec stackoverflow.com/questions/11827569/
0 votes
Le moyen le plus simple et le plus clair de résoudre ce problème consiste à utiliser une requête LINQ récursive. Cette question : stackoverflow.com/questions/732281/expressing-recursion-in-linq a beaucoup de discussions à ce sujet, et este Une réponse particulière explique en détail comment la mettre en œuvre.