Using Linq and C #, trying to get two lists from a list of core elements grouped by two internal lists

Here's the setting:

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 am trying to get the following result in an 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 tried grouping using selectmany, join, and I cannot find a suitable way.

Any Linq wiz around?

PS: In addition, I want to go through the master list only once ...;)

+6
c # linq
source share
1 answer
 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 is probably more efficient to use 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 }; 
+3
source share

All Articles