迭代嵌套列表中的所有项目并返回不同类型的新列表 [英] Iterating all items in nested list and returning new list of different type

查看:62
本文介绍了迭代嵌套列表中的所有项目并返回不同类型的新列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个这样的来源列表:

I have a source list like this:

class Foo {
    public int ID;
    public List<Foo> Children;
}

// Then somewhere else...
Foo root = new Foo(); // The Children is a nested list

然后我可以使用一种新类型进行更改:

Then I have a new type that I have access to make changes to:

class Bar : Foo {
    public string Name;
}

我想做的是创建一个新的Bar,它是上面的root变量的副本,但是每个项目中的Name属性都有一个值.此示例可以是默认值.

What I'd like to do is create a new Bar that is a replica of the root variable above, however has a value for the Name property in each item. It can be a default value for this example.

我已经尝试过rootChildren上的LINQ的Select(...),但是即使那是正确的路线,我也无法简化语法.

I've tried LINQ's Select(...) off the Children of the root but I can't get the syntax down, if that's even the correct route.

到目前为止,该功能仅适用于root列表中第一级子项.我需要它来遍及所有级别的儿童.

I have this so far, which only works on the first level of child items in the root list. I'd need it to go through all levels of children.

Bar = new ObservableCollection<Bar>(root.Children.Select(c => new Bar { Name = "Foo" }));

推荐答案

如果深度合理,则可以使用递归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

这篇关于迭代嵌套列表中的所有项目并返回不同类型的新列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆