2013-05-31 115 views
9

我無法通過指定值獲取密鑰。我能達到這個目標的最好方法是什麼?從值獲取密鑰 - 詞典<字符串,列表<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的返回值將是一個KeyValuePair<string, List<string>>,所以拿到鑰匙,只需使用Key屬性。就像這樣:

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

另外,這裏的查詢語法相當於:

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

是不是'FirstOrDefault(...)。Key'危險的,因爲意外的行爲,當「OrDefault」這裏發生? –

+2

@ChrisMarisic'OrDefault'大小寫返回您正在迭代的類型的默認值。對於引用類型,這是'null',但對於值類型,它將是該類型的新實例。由於'KeyValuePair '是一個值類型(即'struct'),因此'OrDefault'情況不會導致空引用異常。由於'TKey'在這裏是'string',所以新實例的'.Key'將會是'null'。 –

1
var emailAdd = statesToEmailDictionary 
    .FirstOrDefault(x => x.Value != null && 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

我不這麼認爲,至少在單線上。使用非LINQ檢查進行編輯。它和LINQ做的一樣 - 循環每個值直到找到一個值,然後跳出循環。如果它從未找到,則保留null的原始值。 –

+1

實際上,如果你得到一個NullReferenceException,那麼列表本身必須爲null。你可以在lambda內部處理它。更新。 –

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

'KeyValuePair '是一個結構體,所以'temp'永遠不會爲空。 –

+0

我有相同的用例,我必須得到key = [email protected]的價值。我厭倦了下面沒有給予預期的輸出。 var emailAdd = statesToEmailDictionary.FirstOrDefault(x => x.Key ==「[email protected]」)。Value; – 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 

當然,如果有重複的值,這將返回多個KeyValuePair

0
var emailAdd = statesToEmailDictionary.First(x=>x.Value.Contains(state)).Key; 
相關問題