How to flatten tree via LINQ?

后端 未结 14 2365
抹茶落季
抹茶落季 2020-11-22 04:56

So I have simple tree:

class MyNode
{
 public MyNode Parent;
 public IEnumerable Elements;
 int group = 1;
}

I have a I

14条回答
  •  迷失自我
    2020-11-22 05:39

    Every once in awhile I try to scratch at this problem and devise my own solution that supports arbitrarily deep structures (no recursion), performs breadth first traversal, and doesn't abuse too many LINQ queries or preemptively execute recursion on the children. After digging around in the .NET source and trying many solutions, I've finally come up with this solution. It ended up being very close to Ian Stoev's answer (whose answer I only saw just now), however mine doesn't utilize infinite loops or have unusual code flow.

    public static IEnumerable Traverse(
        this IEnumerable source,
        Func> fnRecurse)
    {
        if (source != null)
        {
            Stack> enumerators = new Stack>();
            try
            {
                enumerators.Push(source.GetEnumerator());
                while (enumerators.Count > 0)
                {
                    var top = enumerators.Peek();
                    while (top.MoveNext())
                    {
                        yield return top.Current;
    
                        var children = fnRecurse(top.Current);
                        if (children != null)
                        {
                            top = children.GetEnumerator();
                            enumerators.Push(top);
                        }
                    }
    
                    enumerators.Pop().Dispose();
                }
            }
            finally
            {
                while (enumerators.Count > 0)
                    enumerators.Pop().Dispose();
            }
        }
    }
    

    A working example can be found here.

提交回复
热议问题