2010-02-10 5 views
6

Oto konfiguracja:użyciu LINQ i C#, starając się uzyskać dwie listy z listy przedmiotów mistrzowskich spis dwóch wewnętrznych list

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;} 
} 

uwzględniając następujące dane:

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")); 

Teraz ja” m próbuje uzyskać następujący wynik w oświadczeniu ONE linq:

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")); 

próbowałam grupowanie, używając selectmany, łączy i ca nie wydaje się, aby znaleźć właściwą drogę.

Dowolny wizjer Linq?

PS: Również, chcę przechodzić przez główną listę tylko raz ...;)

Odpowiedz

3
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) 
           }); 

To jest w zasadzie równoważne:

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) 
             ... 
      }; 

To chyba bardziej efektywne użyj POFL (zwykła stara pętla foreach):

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 
      }; 
+0

Inter nie wiem, dlaczego to działa i czy jest optymalna ... –

+0

Boję się wydajności Concata na liście zawierającej kilkaset pozycji ... Masz rację, że może powinienem po prostu użyć pętla foreach. –

Powiązane problemy