使用 LINQ 展平列表列表以获得 parent/child 的列表
Flattening a list of lists, using LINQ, to get a list of parent/child
我正在尝试展平 parent/child 列表,其类型相同 <Person>
。这里的困难在于我会
喜欢将 parents 和 children 合并到一个平面 <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 方法。
谢谢,
var persons = new List<Person>();
parents.ForEach(p => {
persons.Add(p);
persons.AddRange(p.Children);
}
);
foreach(var person in persons)
Console.WriteLine(person.Name);
}
我知道这不是一行,但我想这就是您要查找的内容。
我建议 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));
尝试以下 class :
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);
}
}
}
}
多亏了对我最初 post 的评论,我才能够得到我想要的东西。
该解决方案仅适用于一个级别,这正是我所需要的。它可以递归更深入:
var result = parents.SelectMany(person => person.Children
.Prepend(person))
.Select(p => p.Name);
给了我预期的结果:
parentA
childB
childC
parentD
childE
childF
这让我可以使用展平列表中的所有对象,包括父对象。
我正在尝试展平 parent/child 列表,其类型相同 <Person>
。这里的困难在于我会
喜欢将 parents 和 children 合并到一个平面 <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 方法。
谢谢,
var persons = new List<Person>();
parents.ForEach(p => {
persons.Add(p);
persons.AddRange(p.Children);
}
);
foreach(var person in persons)
Console.WriteLine(person.Name);
}
我知道这不是一行,但我想这就是您要查找的内容。
我建议 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));
尝试以下 class :
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);
}
}
}
}
多亏了对我最初 post 的评论,我才能够得到我想要的东西。
该解决方案仅适用于一个级别,这正是我所需要的。它可以递归更深入:
var result = parents.SelectMany(person => person.Children
.Prepend(person))
.Select(p => p.Name);
给了我预期的结果:
parentA
childB
childC
parentD
childE
childF
这让我可以使用展平列表中的所有对象,包括父对象。