2010-02-10 10 views
6

Aquí está la configuración:El uso de LINQ y C#, tratando de conseguir dos listas de una lista de elementos maestros agrupados por dos listas internas

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

con los siguientes datos:

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

Ahora estoy m tratando de obtener el siguiente resultado en la declaración de una 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")); 

he intentado agrupación, utilizando SelectMany, se une y me ca no parece encontrar la forma adecuada.

Any Linq wiz around?

PS: También, quiero recorrer la lista maestra sólo una vez ...;)

Respuesta

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

Esto es básicamente equivalente a:

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

Es probable que sea más eficiente utilice un POFL (ciclo anterior foreach simple):

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 Sin embargo, no estoy seguro de por qué funciona y si es óptimo ... –

+0

Tengo miedo del rendimiento de Concat en una lista que contiene varios cientos de artículos ... Tienes razón de que tal vez debería simplemente usar un bucle foreach. –

Cuestiones relacionadas