uwzględniając następujące klasy (bardzo uproszczony):LINQ: Jak pobrać elementy z wewnętrznej listy do jednej listy?
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>();
}
i posiadające następujące dane:
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);
Teraz, w jaki sposób uzyskać listę dzieci (z CategoryNumber = 2) z listy rodziców zawierających co najmniej jedno dziecko z CategoryNumber = 1?
mogę wykonać następujące czynności, ale nie wydaje się być optymalny:
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);
Oto co mam do selectedChildren:
IEnumerable<IEnumerable<Child>>
IEnumerable<Child>
- C2 2 20
IEnumerable<Child>
- C4 2 30
Czy możliwe jest tylko jedną listę zawierającą płaską dwojga dzieci elementy zamiast dwóch sub-liście? Jak by to tłumaczyło w LINQ?
@Eric: Tak, składnia zapytań LINQ jest całkiem niezła (i prawdopodobnie nieco lepsza w użyciu w przeciwieństwie do mieszania składni zapytania i metody rozszerzenia). Ilekroć napotykam ten temat, mam jednak wrażenie, że LINQ brakuje operatora konkatenacji (podobnego do Seq.concat w F #), który może być używany jako alternatywa dla SelectMany i jest rzeczywiście bardzo przydatny w innych przypadkach. Proste przeciążenie metody Enumerable.Concat, która pobiera parametr IEnumerable>, wykonałoby to całkiem dobrze. Wszelkie przemyślenia (lub nawet lepsze, plany) dotyczące tego? –
Noldorin
Ah, wygląda na to, że MoreLINQ definiuje ten operator: http://code.google.com/p/morelinq/wiki/OperatorsOverview. Byłoby całkiem fajnie mieć w BCL (wraz z kilkoma innymi, takimi jak Zip). – Noldorin
dzięki ... uratujesz mi dzień – thiagolsilva