2017-10-17 4 views
2

J'ai essayé de déchiffrer comment faire moi-même mais ma compréhension de l'utilisation de LINQ est assez limitée. Ce que j'est deux classes en tant que tels:requête LINQ en utilisant la liste des objets propriété d'un objet

public class Grocery 
{ 
    public string ItemName { get; set; } 
    public List<ItemType> ItemTypes { get; set; } 
} 

public class ItemType 
{ 
    public double Weight { get; set; } 
    public long Quantity { get; set; } 
} 

L'idée étant que vous pouvez avoir un objet Grocery avec ItemName « carottes », et qui se décline en deux différents ItemTypes, par exemple où Poids = 1lb et où Poids = 2lb, avec des quantités différentes de chacun. De toute évidence, il y aura beaucoup plus d'articles que seulement les carottes, et ceux-ci sont stockés dans une liste aussi:

List<Grocery> groceries; 

Ce que je voudrais faire est d'obtenir une liste de toutes les quantités pour tous les produits d'épicerie, étant donné un certain poids. Par exemple. Je pouvais le faire comme ça pour tous les éléments qui ont un type de 1lb:

List<long> quantities = new List<long>(); 

foreach (Grocery grocery in groceries) 
{ 
    foreach (ItemType itemType in grocery.ItemTypes) 
    { 
     if (itemType.Weight == 1) 
     { 
      quantities.Add(itemType.Quantity); 
     } 
    } 
} 

Ce que je voudrais savoir comment je peux obtenir le même résultat en utilisant une expression LINQ, bien que je ne suis pas sûr que ce soit possible sans avoir à utiliser .ForEach et en faisant simplement la même chose que le code ci-dessus mais de manière moins verbeuse (et donc moins lisible). Apprécier ton aide.

Répondre

3

Comme le dit Reno, SelectMany est le chemin à parcourir. Mais plutôt que d'utiliser ForEach pour remplir une liste, allez LINQ tout le chemin:

List<long> quantities = groceries.SelectMany(g => g.ItemTypes) 
    .Where(t => t.Weight == 1) 
    .Select(t => t.Quantity) 
    .ToList(); 
+0

Réponse parfaite, merci pour cela. –

0

SelectMany est votre ami:

groceries.SelectMany(g => g.ItemTypes).Where(t => t.Weight == 1).ToList().ForEach(t => quantities.Add(t.Quantity)); 
+0

Grande réponse merci mais la syntaxe donnée par StriplingWarrior était un peu plus utile. Merci pour l'intro de 'SelectMany' cependant. –

3

Vous pouvez y parvenir en utilisant SelectMany. Afin de reproduire votre traitement foreach, vous pouvez utiliser les éléments suivants:

List<long> quantities = groceries.SelectMany(x => x.ItemTypes) 
    .Where(x => x.Weight == 1) 
    .Select(x => x.Quantity) 
    .ToList(); 

Afin d'obtenir une liste des quantités pour chaque épicerie, comme vous le mentionnez dans votre question, vous pouvez utiliser quelque chose comme ceci:

var groceryQuantities = groceries.Select(g => new 
{ 
    g.ItemName, 
    Quantities = g.ItemTypes 
     .Where(it => it.Weight == 1) 
     .Select(it => it.Quantity) 
     .ToList() 
}).ToList(); 

cela va créer une liste d'objets anonymes, qui ressemble à quelque chose comme ça (en JSON pour la démonstration):

[ 
    { 
     "ItemName": "Grocery #1", 
     "Quantities": [1, 2, 3] 
    }, 
    ... 
] 

Vous pouvez résumer la condition ntities, si c'est ce que vous êtes réellement après. Cela ressemblerait à ceci:

var groceryQuantities = groceries.Select(g => new 
{ 
    g.ItemName, 
    TotalQuantity = g.ItemTypes 
     .Where(it => it.Weight == 1) 
     .Sum(it => it.Quantity) 
}).ToList(); 

Il y a une tonne d'autres choses que vous pouvez faire, mais cela devrait couvrir une façon d'aborder ce dans son ensemble.

+0

Votre réponse initiale était exactement ce que je recherchais, mais StriplingWarrior vient de vous battre. Merci pour l'édition supplémentaire aussi. –