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?
P.S: 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
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With