迭代嵌套列表中的所有项目并返回不同类型的新列表 [英] Iterating all items in nested list and returning new list of different type
问题描述
我有一个这样的来源列表:
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.
我已经尝试过root
的Children
上的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屋!