且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

迭代嵌套列表中的所有项目并返回不同类型的新列表

更新时间:2023-12-05 15:45:16

如果深度合理,则可以使用递归lambda和LINQ轻松完成:

If the depth is reasonable, it can easily be done with recursive lambda and LINQ:

Func<Foo, Bar> resultSelector = null;
resultSelector = source => new Bar
{
    ID = source.ID,
    Name = "Foo",
    Children = source.Children.Select(resultSelector).ToList<Foo>()
};
Foo result = resultSelector(root);

如果深度太大并导致堆栈溢出,则LINQ不适用,您可以对两个显式堆栈使用迭代方法:

If the depth is so big and is causing stack overflow, then LINQ is not applicable, you can use iterative approach with two explicit stacks:

var resultStack = new Stack<Bar>();
var childrenStack = new Stack<List<Foo>.Enumerator>();
var result = new Bar { ID = root.ID, Name = "Foo", Children = new List<Foo>() };
var children = root.Children.GetEnumerator();
while (true)
{
    while (children.MoveNext())
    {
        var child = children.Current;
        var resultChild = new Bar { ID = child.ID, Name = "Foo", Children = new List<Foo>() };
        result.Children.Add(resultChild);
        if (child.Children.Count == 0) continue;
        resultStack.Push(result);
        childrenStack.Push(children);
        result = resultChild;
        children = child.Children.GetEnumerator();
    }
    if (resultStack.Count == 0) break;
    result = resultStack.Pop();
    children = childrenStack.Pop();
}
// Here the result is fully populated