2013-05-31 16 views
9

値を指定してキーを取得できません。私はこれを達成する最良の方法は何ですか?値からキーを取得 - 辞書<string、List <string>>

var st1= new List<string> { "NY", "CT", "ME" }; 
var st2= new List<string> { "KY", "TN", "SC" }; 
var st3= new List<string> { "TX", "OK", "MO" }; 
var statesToEmailDictionary = new Dictionary<string, List<string>>(); 
statesToEmailDictionary.Add("[email protected]", st1); 
statesToEmailDictionary.Add("[email protected]", st2); 
statesToEmailDictionary.Add("[email protected]", st3); 

var emailAdd = statesToEmailDictionary.FirstOrDefault(x => x.Value.Where(y => y.Contains(state))).Key; 

答えて

17

FirstOrDefaultからの戻り値は、単純にKeyプロパティを使用し、キーを取得するので、KeyValuePair<string, List<string>>になります。

var emailAdd = 
    (from p in statesToEmailDictionary 
    where p.Value.Contains(state) 
    select p.Key) 
    .FirstOrDefault(); 
+0

が予期しない動作のように、 'FirstOrDefault(...)。Key'は危険ではありませんが返されますがある場合? –

+2

@ChrisMarisic 'OrDefault'ケースは、反復処理しているタイプのデフォルト値を返します。参照型の場合は 'null'ですが、値型の場合はその型の新しいインスタンスになります。 'KeyValuePair 'は値型(' struct')であるため、' OrDefault 'の場合はnull参照例外が発生しません。 'TKey'は' string'なので、その新しいインスタンスの '.Key'は' null'になります。 –

1
var emailAdd = statesToEmailDictionary 
    .FirstOrDefault(x => x.Value != null && x.Value.Contains(state)) 
    .Key; 

しかし、あなたはパフォーマンスを探しているなら、私はあなたの辞書を逆転しての辞書を作成することをお勧めしたい:

var emailAdd = statesToEmailDictionary 
    .FirstOrDefault(x => x.Value.Contains(state)) 
    .Key; 

はまた、ここで同等のクエリ構文にあります。このような<state, email>あなたが探していることを行う。

// To handle when it's not in the results 
string emailAdd2 = null; 
foreach (var kvp in statesToEmailDictionary) 
{ 
    if (kvp.Value != null && kvp.Value.Contains(state)) 
    { 
     emailAdd2 = kvp.Key; 
     break; 
    } 
} 
+0

'NullReferenceException'を処理する方法はありますか? –

+0

私はそうは思わない、少なくとも1ライナーで。非LINQチェックで編集しました。これは、LINQと同じことを行います。それは、LINQが見つかるまで各値をループし、その後、ループから抜け出します。見つからない場合は、元のnull値が保持されます。 –

+1

実際、NullReferenceExceptionが発生した場合、リスト自体はnullである必要があります。あなたはラムダの中でそれを扱うことができます。更新しました。 –

-1
var temp = statesToEmailDictionary.Where(x => x.Value.Contains(state)).FirstOrDefault(); 
var emailAdd = temp != null ? temp.Key : string.Empty; 
+1

'KeyValuePair 'は構造体なので、 'temp'は決してnullになりません。 –

+0

私はkey = [email protected]の値を取得しなければならない同じユースケースを持っています。 var emailAdd = statesToEmailDictionary.FirstOrDefault(x => x.Key == "[email protected]")。値。 – Blossom

2

は、私はあなたがしたいと思う:

言及しなかったこのスレッドではどのような誰も
var emailAdd = statesToEmailDictionary.FirstOrDefault(x => x.Value.Any(y => y.Contains(state))).Key; 
1

FirstOrDefault方法はLinqを通じてのみ利用可能であるということである。

using System; 
using System.Collections.Generic; 
// FirstOrDefault is part of the Linq API 
using System.Linq; 

namespace Foo { 
    class Program { 
     static void main (string [] args) { 
      var d = new Dictionary<string, string>() { 
       { "one", "first" }, 
       { "two", "second" }, 
       { "three", "third" } 
      }; 
      Console.WriteLine (d.FirstOrDefault (x => x.Value == "second").Key); 
     } 
    } 
} 
0

単純なLINQのちょうどそれをするには

もちろん
Dim mKP = (From mType As KeyValuePair(Of <Key type>, <Value type>) In <Dictionary> 
      Where mType.Value = <value seeked> Select mType).ToList 

If mKP.Count > 0 then 
    Dim value as <value type> = mKP.First.Value 
    Dim key as <Key type> = mKP.First.Key 
End if 

重複する値は「OrDefaultは」ここに発生したときに、これは、複数のKeyValuePair

0
var emailAdd = statesToEmailDictionary.First(x=>x.Value.Contains(state)).Key; 
関連する問題