使用 LINQ 展平列表列表以获取父/子列表
Posted
技术标签:
【中文标题】使用 LINQ 展平列表列表以获取父/子列表【英文标题】:Flattening a list of lists, using LINQ, to get a list of parent/child 【发布时间】:2021-07-07 16:48:43 【问题描述】:我正在尝试展平相同 <Person>
类型的父/子列表。这里的困难是我会
喜欢将父母和孩子合并到一个平面 <Person>
列表中。
我得到的最接近的是:
class Person
public string Name get; set;
public List<Person> Children get; set;
List<Person> parents = new List<Person>()
new Person()
Name = "parentA",
Children = new List<Person>()
new Person() Name = "childB" ,
new Person() Name = "childC"
,
new Person()
Name = "parentD",
Children = new List<Person>()
new Person() Name = "childE" ,
new Person() Name = "childF"
;
var result = parents.SelectMany(parent => parent.Children
.Select(child => parent.Name + ", " + child.Name));
这给了我结果:
parentA, childB
parentA, childC
parentD, childE
parentD, childF
我正在寻找的是获得<Person>
列表,例如:
parentA
childB
childC
parentD
childE
childF
保持顺序,否则性能并不重要。但我希望,如果可能,坚持纯 LINQ 和 LINQ 方法。
谢谢,
【问题讨论】:
***.com/questions/11830174/…SelectMany(parent => parent.Children.Append(parent).Select(x => x.Name))
如果你只需要深入一层?
如果您想保留先父后子的顺序,就像您的问题一样,您可以使用Prepend
而不是Append
。 parents.SelectMany(p => p.Children.Prepend(p));
你们明白了,这正是我要找的。谢谢!我可以将评论标记为解决方案吗?
【参考方案1】:
如果你想要一层深度,我建议将Concat
与SelectMany
结合使用:
var parents = ...
var result = parents
.SelectMany(person => new Person[] person.Concat(person.Children))
.Select(person => person.Name); // if we want just names
// Let's have a look
Console.WriteLine(string.Join(Environment.NewLine, result));
【讨论】:
Dmitry,你的回答也很有帮助,因为在代码中的某个地方, .Prepend() 会因为某种原因而不是 ObservableCollection 上的方法(仍然没有想到那个还没有)。然而,这完美无缺。谢谢。【参考方案2】:var persons = new List<Person>();
parents.ForEach(p =>
persons.Add(p);
persons.AddRange(p.Children);
);
foreach(var person in persons)
Console.WriteLine(person.Name);
我知道这不是一行,但我想这就是你要找的。p>
【讨论】:
【参考方案3】:尝试以下课程:
class Person
public static DataTable dt get;set;
public string Name get; set;
public List<Person> Children get; set;
public void GetTree(Person root)
DataTable dt = new DataTable();
dt.Columns.Add("Parent Name", typeof(string));
dt.Columns.Add("Child Name", typeof(string));
GetTreeRecursive(root, "");
public void GetTreeRecursive(Person person, string parentName)
foreach(Person child in person.Children)
dt.Rows.Add(parentName, child.Name);
if (child.Children != null)
GetTreeRecursive(child, child.Name);
【讨论】:
【参考方案4】:感谢我最初帖子中的 cmets,我能够得到我想要的东西。
该解决方案仅适用于一个级别,这正是我所需要的。不过,它可以递归更深入:
var result = parents.SelectMany(person => person.Children
.Prepend(person))
.Select(p => p.Name);
给了我预期的结果:
parentA
childB
childC
parentD
childE
childF
这让我可以使用展平列表中的所有对象,包括父对象。
【讨论】:
以上是关于使用 LINQ 展平列表列表以获取父/子列表的主要内容,如果未能解决你的问题,请参考以下文章