Tener las siguientes clases (muy simplificado):LINQ: ¿Cómo obtener elementos de una lista interna en una lista?
public class Child
{
public string Label;
public int CategoryNumber;
public int StorageId;
}
public class Parent
{
public string Label;
public List<Child> Children = new List<Child>();
}
Y con los siguientes datos:
var parents = new List<Parent>();
var parent = new Parent() {Label="P1"};
parent.Children.Add(new Child() {Label="C1", CategoryNumber=1, StorageId=10});
parent.Children.Add(new Child() {Label="C2", CategoryNumber=2, StorageId=20});
parents.Add(parent);
parent = new Parent() {Label="P2"};
parent.Children.Add(new Child() {Label="C3", CategoryNumber=1, StorageId=10});
parent.Children.Add(new Child() {Label="C4", CategoryNumber=2, StorageId=30});
parents.Add(parent);
parent = new Parent() {Label="P3"};
parent.Children.Add(new Child() {Label="C5", CategoryNumber=3, StorageId=10});
parent.Children.Add(new Child() {Label="C6", CategoryNumber=2, StorageId=40});
parents.Add(parent);
Ahora, ¿cómo iba a obtener una lista de los niños (con CategoryNumber = 2) de la lista de padres que contienen al menos un hijo con CategoryNumber = 1?
que puede hacer lo siguiente, pero no parece ser óptimo:
var validParents = from p in parents
where p.Children.Any (c => c.CategoryNumber==1)
select p;
var selectedChildren = validParents.Select(p => from c in p.Children
where c.CategoryNumber == 2
select c);
Esto es lo que me pasa por selectedChildren:
IEnumerable<IEnumerable<Child>>
IEnumerable<Child>
- C2 2 20
IEnumerable<Child>
- C4 2 30
¿Es posible sólo tienen una lista plana que contiene los elementos de dos niños en vez de dos sub-lista? ¿Cómo se traduciría en LINQ?
@Eric: Sí, la sintaxis de la consulta LINQ para esto es bastante buena (y probablemente un poco mejor para usarla que para mezclar la sintaxis del método de consulta y extensión). Sin embargo, cada vez que encuentro este tema, siento que a LINQ le falta un operador de concatenación (similar a Seq.concat en F #), que podría usarse como alternativa a SelectMany, y de hecho es muy útil en otros casos. Una sobrecarga sencilla del método Enumerable.Concat que toma un parámetro IEnumerable> haría bastante bien el trabajo. ¿Alguna idea (o incluso mejor, planes) con respecto a esto? –
Noldorin
Ah, parece que MoreLINQ define este operador: http://code.google.com/p/morelinq/wiki/OperatorsOverview. Sin embargo, sería bastante bueno tener en el BCL (junto con algunos otros como Zip). – Noldorin
gracias ... me salvaste el día – thiagolsilva