使用 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);
    }

我知道这不是一行,但我想这就是您要查找的内容。

我建议 ConcatSelectMany 结合使用,如果你只想要 一层深度 :

 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 

这让我可以使用展平列表中的所有对象,包括父对象。