2010-02-10 32 views
6

這裏分組主項的列表獲取兩個列表的設置:使用LINQ和C#,試圖從兩個內部列表

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

具有下列數據:

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

現在的我試圖讓在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")); 

我試過分組,使用的SelectMany加入我CA似乎沒有找到正確的方法。

任何Linq圍繞?

PS:另外,我想穿越主列表中只有一次...;)

回答

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

這基本上等同於:

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

它可能更有效使用POFL(普通老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 esting ...我不知道爲什麼它可以工作,如果它是最佳的... – 2010-02-10 18:56:18

+0

我害怕Concat在包含數百個項目的列表上的表現......你說得對,也許我應該簡單地使用一個foreach循環。 – 2010-02-10 19:03:25