2017-06-18 10 views
-2

私はアイテムのリストを持ち、各アイテムにはコンポーネントのリストがあります。LINQを使用してオブジェクトリストのリストをフィルタリングする方法

public class Item 
{ 
    Item(string name) 
    { 
     ItemName = name; 
    } 
    public string ItemName { get; private set; } 
    public List<Component> Components {get;set;} 
} 

public class Component 
{ 
    public string Name {get;set;} 
    public string Status {get;set;} 
} 

// Example 
Item 1 
    Component 1 - Status A 
    Component 2 - Status B 
    Component 3 - Status A 
Item 2 
    Component 1 - Status C 
    Component 2 - Status C 
    Component 3 - Status A 
Item 3 
    Component 1 - Status C 
    Component 2 - Status C 
    Component 3 - Status D 

LINQを使用すると、ステータスAまたはBのコンポーネントを持つすべてのアイテムのコンポーネントだけを取得できますか?

次のソリューションは、私が探していますされていないものを:

var statuses = { "A" , "B" } 
var result= items 
       .Where(i => i.Components 
       .Any(c => statuses.Contains(c.Status)) 
       .ToList(); 

このソリューションは、少なくとも一つの成分が私たちの例では、状態AまたはBを有している場合には、すべてのコンポーネントを持つアイテムを返して、アイテム1とアイテム2はすべてのコンポーネントとともに返されます。結果は次のようになりますステータスAとBとの

Item 1 
    Component 1 - Status A 
    Component 2 - Status B 
    Component 3 - Status A 
Item 2 
    Component 3 - Status A 

コンポーネントのみが返される。

Item 1 
    Component 1 - Status A 
    Component 2 - Status B 
    Component 3 - Status A 
Item 2 
    Component 1 - Status C 
    Component 2 - Status C 
    Component 3 - Status A 

Iは、結果がされる同様のソリューションが必要になります。

このタスクを達成する正しい構文は何ですか?

EDIT:要求ごと

、項目の初期化:

var items = new List<Item> 
{ 
    new Item("Item 1") 
    { 
     Components = new List<Component> 
     { 
      new Component {Name ="Component1", Status = "A"}, 
      new Component {Name ="Component2", Status = "B"}, 
      new Component {Name ="Component3", Status = "A"} 
     } 
    }, 
    new Item("Item 2") 
    { 
     Components = new List<Component> 
     { 
      new Component {Name ="Component1", Status = "C"}, 
      new Component {Name ="Component2", Status = "C"}, 
      new Component {Name ="Component3", Status = "A"} 
     } 
    }, 
    new Item("Item 3") 
    { 
     Components = new List<Component> 
     { 
      new Component {Name ="Component1", Status = "C"}, 
      new Component {Name ="Component2", Status = "C"}, 
      new Component {Name ="Component3", Status = "D"} 
      } 
    } 
}; 
+0

サンプルデータの初期化を示す短いC#サンプルを書くことができれば、いくつかの解決策を書くのが早くなります。 – mjwills

+0

'.Any(c => statuses.Contains(c.Status))'を '.All(c => statuses.Contains(c.Status))'に変更します。完了 – Nkosi

+2

SelectManyはトリックを行います –

答えて

2

探索することができアベニュー:このため

var statuses = new HashSet<string>() { "A", "B" }; 
var result = items 
    .Where(i => i.Components.Any(c => statuses.Contains(c.Status))) 
    .Select(z => new Item(z.ItemName) { Components = z.Components.Where(y => statuses.Contains(y.Status)).ToList() }) 
    .ToList(); 

を仕事に、あなたが必要ですItemコンストラクタをpublicにします。

+0

私のために働いていない、いくつかのエラーを取得して、それらの1つは: エラー\t CS0103 \t名前 '選択'は現在存在しません – ehh

+0

私は謝罪します。やってみよう。 – mjwills

+0

魅力的な作品 – ehh

0

私は完全性のためにこれを含めています(そしてコメントする評判が十分でないため)。あなたが含まれているアイテムのないコンポーネントだけを望むなら、このようにすることができます。

string[] statuses = { "A", "B" }; 
var things = items.SelectMany(x => x.Components.Where(y => statuses.Contains(y.Status))); 

foreach (var thing in things) 
    Console.WriteLine(thing); 
関連する問題