使用Linq和C#,尝试从两个内部列表分组的主项目列表中获取两个列表

时间:2010-02-10 18:36:06

标签: c# linq

以下是设置:

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

现在我试图在一个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加入分组,但我似乎无法找到正确的方法。

任何Linq奇才?

P.S:另外,我想只遍历主列表一次......;)

1 个答案:

答案 0 :(得分: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
             };