2010-10-23 29 views
25

Jak uzyskać klucz słownika za pomocą wartości słownika?Pobierz klucz słownika, używając wartości słownika

gdy coraz wartość używając klawisza Jej tak:

Dictionary<int, string> dic = new Dictionary<int, string>(); 

dic.Add(1, "a"); 

Console.WriteLine(dic[1]); 
Console.ReadLine(); 

Jak zrobić odwrotnie?

+0

możliwy duplikat [Uzyskiwanie klucza wartości ogólnego słownika?] (Http://stackoverflow.com/questions/255341/getting-key-of-value-of-a-generic-dictionary) – bluish

Odpowiedz

61

Słownik jest naprawdę przeznaczony do wyszukiwania w jedną stronę z Key-> Value.

można zrobić odwrotny używać LINQ:

var keysWithMatchingValues = dic.Where(p => p.Value == "a").Select(p => p.Key); 

foreach(var key in keysWithMatchingValues) 
    Console.WriteLine(key); 

sobie sprawę, że może istnieć wiele kluczy o tej samej wartości, więc wszelkie właściwe wyszukiwarka zwróci zbiór kluczy (co jest dlaczego foreach istnieje powyżej) .

+2

ack, beat ja przez 35 sekund! :) –

+0

Zamierzam zgadnąć, że jest to prawdopodobnie szybsze niż za każdym razem poprzez keyvaluepairs, ale nie jest szybsze niż odwrócenie słownika wokół huh? Będę musiał sam go przygotować, aby zobaczyć z ciekawości, ale szybciej byłoby sprawić, by słownik był inny? – user99999991

+1

@ user999999928 Jest to zasadniczo takie samo jak robienie foreach przez słownik. Jeśli masz zamiar robić wiele wyszukiwań, budowanie "odwróconego" słownika (który wymaga kolekcji dla wartości) sprawiłoby, że wyszukiwania byłyby szybsze, ale wstawienia/zmiany musiałyby być obsługiwane w obu. –

21

Brutalna siła.

 int key = dic.Where(kvp => kvp.Value == "a").Select(kvp => kvp.Key).FirstOrDefault(); 
+2

+1 Dla Brute Force;) –

+4

int key = dic.FirstOrDefault (kvp => kvp.Value == "a"). Klucz; – cilerler

+1

, który wyrzuci wyjątek, jeśli nie ma klucza o tej wartości. ('FirstOrDefault' zwraca null, bierzesz' .Key' of null) –

10

Można także skorzystać z następującej metody rozszerzenie dostać kluczyk ze słownika przez wartość

public static class Extensions 
{ 
    public static bool TryGetKey<K, V>(this IDictionary<K, V> instance, V value, out K key) 
    { 
     foreach (var entry in instance) 
     { 
      if (!entry.Value.Equals(value)) 
      { 
       continue; 
      } 
      key = entry.Key; 
      return true; 
     } 
     key = default(K); 
     return false; 
    } 
} 

użycie jest tak prosty

int key = 0; 
if (myDictionary.TryGetKey("twitter", out key)) 
{ 
    // successfully got the key :) 
} 
+0

+1), ponieważ zain mówi nowy sposób implementacji tego poprzez metody Extension. – Singleton

2

łatwy sposób get jeden klucz:

public static TKey GetKey<TKey,TValue>(Dictionary<TKey, TValue> dictionary, TValue Value) 
    { 
     List<TKey> KeyList = new List<TKey>(dictionary.Keys); 
     foreach (TKey key in KeyList) 
      if (dictionary[key].Equals(Value)) 
       return key; 
     throw new KeyNotFoundException(); 
    } 

i wielokrotność klawiszy:

public static TKey[] GetKeys<TKey, TValue>(Dictionary<TKey, TValue> dictionary, TValue Value) 
    { 
     List<TKey> KeyList = new List<TKey>(dictionary.Keys); 
     List<TKey> FoundKeys = new List<TKey>(); 
     foreach (TKey key in KeyList) 
      if (dictionary[key].Equals(Value)) 
       FoundKeys.Add(key); 
     if (FoundKeys.Count > 0) 
      return FoundKeys.ToArray(); 
     throw new KeyNotFoundException(); 
    } 
0

Zdaję sobie sprawę, że jest to stare pytanie, ale chciałem dodać coś myślałem.

Jeśli wiesz, że będzie tylko jeden klucz do jednej wartości, będziesz musiał sprawdzić wartość, a także klucz; możesz utworzyć dwa osobne słowniki. Jeden z oryginalnym kluczem jako klucz i wartość jako wartość, a drugi z kluczem jako wartość i wartość jako klucz.

Teraz uwaga na ten temat; zużywa więcej zasobów komputera, ale domyślam się, że jest to szybsze niż brutalne forsowanie LINQ i foreach.