2013-05-31 24 views
9

Bir değer belirterek anahtarı almada sorun yaşıyorum. Bunu başarabilmemin en iyi yolu nedir?Değeri anahtarı alın - Sözlük <dize, Liste <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; 

cevap

17

FirstOrDefault dönüş değeri basitçe Key özelliğini kullanın anahtarı almak çok, bir KeyValuePair<string, List<string>> olacaktır. Şunun gibi:

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

, burada sorgu sözdiziminde eşdeğer:

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

beklenmeyen bir davranış olduğu gibi 'FirstOrDefault (...). Key' tehlikeli değil mi dönecektir varsa ? –

+2

@ChrisMarisic 'OrDefault' durumu, üzerinde yinelediğiniz türün varsayılan değerini döndürür. Referans türleri için, bu 'null' değil, değer türleri için, bu türün yeni bir örneği olacaktır. 'KeyValuePair 'bir değer türü olduğundan (yani' struct '),' OrDefault 'durumu boş referans istisnasıyla sonuçlanmayacaktır. Buradaki "TKey", "string" olduğundan, bu yeni durumun ".Key" i "null" olacaktır. –

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

Ama performans arıyorsanız, senin sözlüğü ters ve bir sözlük oluşturmak öneririm Aradığınızı yapmak için <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" işlemek için herhangi bir yol? –

+0

En azından bir linerde sanmıyorum. LINQ olmayan bir kontrol ile düzenlenmiştir. LINQ'un yaptığı ile aynı şeyi yapar - her değeri bir tane buluncaya kadar çevirir, daha sonra döngüden ayrılır. Asla bir tane bulamazsa, null'un orijinal değeri korunur. –

+1

Aslında, bir NullReferenceException alıyorsanız, listenin kendisi null olmalıdır. Bunu lambda içinde halledebilirsin. Güncellenmiş. –

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

'KeyValuePair ' bir yapıdır, bu yüzden 'temp' asla boş olmaz. –

+0

Bekleyen çıktı vermeyen anahtar = [email protected] altta iken değeri almak zorunda olduğum aynı kullanım durumum var. var emailAdd = statesToEmailDictionary.FirstOrDefault (x => x.Key == "[email protected]") Değeri; – Blossom

2

İstediğin düşünüyorum:

söz başarısız Bu Konuda Ne herkes
var emailAdd = statesToEmailDictionary.FirstOrDefault(x => x.Value.Any(y => y.Contains(state))).Key; 
1

FirstOrDefault yöntem Linq ile kullanılabilir olmasıdır:

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

Basit Linq sadece

Tabii
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 

yinelenen değerler "OrDefault" Burada ortaya çıktığında bu birden fazla KeyValuePair

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