简体   繁体   中英

Using Linq and C#, trying to get two lists from a list of master items grouped by two inner lists

Here's the setup:

public class Parent
{
    public List<Child> ChildrenA = new List<Child>();
    public List<Child> ChildrenB = new List<Child>();
}

public class Child
{
    public Child (string name) {Name=name;}
    public string Name {get;set;}
}

Having the following data:

var parents = new List<Parent>();
parents.Add (new Parent());
parents[0].ChildrenA.Add (new Child("A1"));
parents[0].ChildrenA.Add (new Child("A2"));
parents[0].ChildrenB.Add (new Child("B1"));
parents.Add (new Parent());
parents[1].ChildrenA.Add (new Child("A3"));

Now I'm trying to get the following result in ONE linq statement:

var result = ... // would be an anonymous type

Assert.That (result.ChildrenA.Count, Is.EqualTo(3));
Assert.That (result.ChildrenA[0].Name, Is.EqualTo("A1"));
Assert.That (result.ChildrenA[1].Name, Is.EqualTo("A2"));
Assert.That (result.ChildrenA[2].Name, Is.EqualTo("A3"));

Assert.That (result.ChildrenB.Count, Is.EqualTo(1));
Assert.That (result.ChildrenB[0].Name, Is.EqualTo("B1"));

I've tried grouping, using selectmany, joins and I can't seem to find the proper way.

Any Linq wiz around?

PS: Also, I want to traverse the master list only once... ;)

var result = parents.Aggregate(
                     new
                     {
                         ChildrenA = Enumerable.Empty<Child>(),
                         ChildrenB = Enumerable.Empty<Child>()
                     },
                     (a, p) => new
                               {
                                   ChildrenA = a.ChildrenA.Concat(p.ChildrenA),
                                   ChildrenB = a.ChildrenB.Concat(p.ChildrenB)
                               });

This is basically equivalent to:

var result = new
             {
                 ChildrenA = Enumerable.Empty<Child>()
                                       .Concat(parents[0].ChildrenA)
                                       .Concat(parents[1].ChildrenA)
                                       .Concat(parents[2].ChildrenA)
                                       ...,

                 ChildrenB = Enumerable.Empty<Child>()
                                       .Concat(parents[0].ChildrenB)
                                       .Concat(parents[1].ChildrenB)
                                       .Concat(parents[2].ChildrenB)
                                       ...
             };

It's probably more efficient to use a POFL (plain old foreach loop):

var childrenA = new List<Child>();
var childrenB = new List<Child>();

foreach (var parent in parents)
{
    childrenA.AddRange(parent.ChildrenA);
    childrenB.AddRange(parent.ChildrenB);
}

var result = new
             {
                 ChildrenA = childrenA,
                 ChildrenB = childrenB
             };

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM