2016-04-01 5 views
1

私はListの値を持つ辞書を持っています。特定のキーに属する特定の要素をリストから選択したいと考えています。私はこれまでのところ、これを試してみました:LINQを使用してキーが存在する場合、辞書から値を選択

Dictionary<int, List<bool>> dic = new Dictionary<int, List<bool>>(); 
dic.Add(1, new List<bool> { true, true, false }); 
var works = dic.Where(x => x.Key == 1).SingleOrDefault().Value.Where(x => x == true).ToList(); 
var doesNotWork = dic.Where(x => x.Key == 2).SingleOrDefault().Value.Where(x => x == true).ToList(); 

1に等しいキーは、私は2つの要素でList<bool>を取得したがってがあるので最初のLINQ作品。 値がnullであるため、2番目のLINQが機能しません。辞書に適切なキーがない場合、空のList<bool>が得られるように、どのようにそのLINQを書き直すことができますか?

私は、デフォルトの要素にValueの代わりに空のリストがあると思っていたので、私のアプローチがうまくいくと思いました。

最も簡単な解決策は、あなたが値を二度チェックしないように、すなわち、 Dictionary<T>.TryGetValueを使用することです
+1

あなたの鍵を保持するいくつかの変数である' Dictionary.TryGetValue(使用して辞書から値を取得しようとしない理由

var shouldWork = dic[key]?.Where(x => x == true).ToList() ?? new List<bool>();

:ヌルのためのチェックは、あなたがこれに上記のLINQクエリを簡素化することができ? – ASh

+0

'Take(1)'は1つの項目または空の列挙を返します。これは、あなたの望むことですか? (x => x.Key == 2).Take(1).Select(kvp => kvp.Value).SelectMany(x => x).ToList(); 'しかし、LINQ解析するのが難しいですが、代わりに通常のC#で行います。 –

+0

DictionaryのContainKey()メソッドを使用します。 – jdweng

答えて

2

免責事項:C#6.0以降でのみ動作(VS 2015+)

あなたは本当にあなたが?.演算子(ヌル-条件演算子)を使用して、このような行を取得することができますLINQを使用して、単一の行でそれをしたい場合:

var shouldWork = dic.Where(x => x.Key == 2)?.SingleOrDefault().Value.Where(x => x == true).ToList() ?? new List<bool>();

これは、shouldWorkをlinqクエリの結果または空のリストのいずれかに設定します。顧客=

int型の長さ.LENGTH ??:あなたが欲しいものでnew List<bool>()を置き換えることができ

はgithubのサイトから、特にこの例でC#6.0の新機能の詳細については、MSDN post hereGithub post hereを参照してください? 0;顧客がnullの場合// 0

それは

ヌル条件演算子展示短絡挙動、部材の直後のチェーンがアクセス をどのように働くかの説明

は、要素 にアクセスし以来:?。オリジナル 受信機は

編集nullではなかった場合の呼び出しにのみ実行されます`)キーが

+0

これは素晴らしい作品です。他の可能な解決方法を使用することには不利な点がありますか? – gartenriese

+0

私が読んだところからは、それはかなり構文的な砂糖であり、コンパイルされたときに同じコードに分解されます。私は100%の確実性でこれを知らない –

0

 Dictionary<int, List<bool>> dic = new Dictionary<int, List<bool>>(); 
     dic.Add(1, new List<bool> { true, true, false }); 

     List<bool> match = null; 
     var found = dic.TryGetValue(2, out match); 
     if (!found) match = new List<bool>(); 
+1

私は2を価値と考えると思いますか?彼は欠けているキーのための実用的な解決策を望んでいました。つまり、ここでは「2」は存在しないキーです。 :) – mwilczynski

1

なぜそれがLINQする必要がありますか。

List<bool> works1 = dic.ContainsKey(1) ? dic[1] : new List<bool>(); 
+0

これは '.Contains()'を2回使用します。 :) – mwilczynski

+0

@mwilczynskiだから、それは0(1)操作です。 – Paparazzi

+0

これは不必要なチェックです。 :) – mwilczynski

0

この

Dictionary<int, List<bool>> dic = new Dictionary<int, List<bool>>(); 
dic.Add(1, new List<bool> { true, true, false }); 
var works = !dic.ContainsKey(1)? new List<bool>(): dic[1].Where(x => x == true).ToList(); 
var doesNotWork = !dic.ContainsKey(2) ? new List<bool>(): dic[2].Where(x => x == true).ToList(); 
2

を試してみてくださいあなたはDictionaryで鍵を見つけるために、LINQを使用すべきではない - ContainsKey /インデクサ組以上の最適TryGetValueからDictionaryはそれを行うためのより効率的な方法があります。例えば

int key = 2; 

(A)

var result = dic.ContainsKey(key) ? dic[key].Where(x => x == true).ToList() : new List<bool>(); 

(B)

List<bool> values; 
var result = dic.TryGetValue(key, out values) ? values.Where(x => x == true).ToList() : new List<bool>(); 
+0

LINQを使用してはいけないと答えていますが、LINQを使用しているはずです。 – gartenriese

+0

私は**キー**部分を意味しました - LINQは残りの部分でOKです。 –

+0

安心していただけますか?なぜdic [key] .Where(x => x == true).ToList()? dic [key]は値を返します。 – Paparazzi

0

あなたは奇妙な結果を取得したい、とにかく、このコード助けます:

var reslt = (dic.FirstOrDefault(x => x.Key == 2).Value ?? new List<bool>(0)) 
.Where(x => x) 
.ToList(); 

Dictionaryのキーが一意であるため、SingleOrDefault()メソッドが正しくありません。

x => x == trueも変です。

0

それはLINQする必要がなぜ私たちは知りませんが、これはオプションのようになります。

var nowItWork = dic.Where(x => x.Key == 2).SelectMany(x => x.Value).Where(x => x).ToList();