Mise à jour :
Pour les personnes intéressées par le niveau d'emboîtement (profondeur). L'une des bonnes choses de l'implémentation explicite de la pile d'énumérateurs est qu'à tout moment (et en particulier lors de la cession de l'élément), l'élément stack.Count
représente la profondeur de traitement actuelle. En prenant cela en compte et en utilisant les tuples de valeur de C#7.0, nous pouvons simplement modifier la déclaration de la méthode comme suit :
public static IEnumerable<(T Item, int Level)> ExpandWithLevel<T>(
this IEnumerable<T> source, Func<T, IEnumerable<T>> elementSelector)
et yield
déclaration :
yield return (item, stack.Count);
Ensuite, nous pouvons mettre en œuvre la méthode originale en appliquant une simple Select
sur ce qui précède :
public static IEnumerable<T> Expand<T>(
this IEnumerable<T> source, Func<T, IEnumerable<T>> elementSelector) =>
source.ExpandWithLevel(elementSelector).Select(e => e.Item);
Original :
Étonnamment, personne (même Eric) n'a montré le portage itératif "naturel" d'une DFT récursive de pré-ordre, alors le voici :
public static IEnumerable<T> Expand<T>(
this IEnumerable<T> source, Func<T, IEnumerable<T>> elementSelector)
{
var stack = new Stack<IEnumerator<T>>();
var e = source.GetEnumerator();
try
{
while (true)
{
while (e.MoveNext())
{
var item = e.Current;
yield return item;
var elements = elementSelector(item);
if (elements == null) continue;
stack.Push(e);
e = elements.GetEnumerator();
}
if (stack.Count == 0) break;
e.Dispose();
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.