So I have simple tree:
class MyNode
{
public MyNode Parent;
public IEnumerable Elements;
int group = 1;
}
I have a I
Update:
For people interested in level of nesting (depth). One of the good things about explicit enumerator stack implementation is that at any moment (and in particular when yielding the element) the stack.Count
represents the currently processing depth. So taking this into account and utilizing the C#7.0 value tuples, we can simply change the method declaration as follows:
public static IEnumerable<(T Item, int Level)> ExpandWithLevel(
this IEnumerable source, Func> elementSelector)
and yield
statement:
yield return (item, stack.Count);
Then we can implement the original method by applying simple Select
on the above:
public static IEnumerable Expand(
this IEnumerable source, Func> elementSelector) =>
source.ExpandWithLevel(elementSelector).Select(e => e.Item);
Original:
Surprisingly no one (even Eric) showed the "natural" iterative port of a recursive pre-order DFT, so here it is:
public static IEnumerable Expand(
this IEnumerable source, Func> elementSelector)
{
var stack = new Stack>();
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();
}
}