2010-10-23 28 views
25

Come ottenere la chiave del dizionario utilizzando il valore del dizionario?Ottieni la chiave del dizionario utilizzando il valore del dizionario

quando ottiene il valore con il tasto la sua in questo modo:

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

dic.Add(1, "a"); 

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

Come fare il contrario?

+0

possibile duplicato di [Ottenere la chiave di valore di un dizionario generico?] (Http://stackoverflow.com/questions/255341/getting-key-of-value-of-a-generic-dictionary) – bluish

risposta

61

Un dizionario è realmente destinato alla ricerca unidirezionale da Chiave-> Valore.

Si può fare l'uso contrario LINQ:

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

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

Rendetevi conto che ci possono essere più chiavi con lo stesso valore, in modo da qualsiasi ricerca corretta restituirà un insieme di chiavi (che è il motivo per cui il foreach esiste al di sopra) .

+2

ack, beat me di 35 secondi! :) –

+0

Devo indovinare che questo è probabilmente più veloce di un valore per ogni chiave di chiave, ma non è più veloce di invertire il dizionario in giro eh? Dovrò farlo da solo per vedere la curiosità, ma sarebbe più veloce solo a rendere il dizionario diverso, giusto? – user99999991

+1

@ user999999928 Questo è praticamente lo stesso di fare un foreach attraverso il dizionario. Se si stanno facendo molte ricerche, la creazione di un dizionario "invertito" (che richiede una raccolta per il valore) renderebbe le ricerche più veloci, ma gli inserimenti/i cambiamenti dovrebbero essere gestiti in entrambi. –

21

Forza bruta.

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

+1 For Brute Force;) –

+4

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

+1

che genererà un'eccezione se non c'è una chiave con quel valore, però. ('FirstOrDefault' restituisce null, si prenda' .Key' di null) –

10

È inoltre possibile utilizzare il seguente metodo di estensione per ottenere chiave dal dizionario per valore

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; 
    } 
} 

l'utilizzo è anche così semplice

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

+1 come zain sta dicendo un nuovo modo di implementare questo attraverso i metodi di estensione. – Singleton

2

modo semplice per ottenere una chiave:

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(); 
    } 

e per i tasti multipli:

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

Mi rendo conto che è una vecchia questione, ma ha voluto aggiungere qualcosa ho pensato.

Se sai che ci sarà solo una chiave per un valore e dovrai cercare sia il valore che la chiave; puoi creare due dizionari separati. Uno con la chiave originale come chiave e valore come valore e il secondo con la chiave come valore e valore come chiave.

Ora una nota a margine su questo; consuma più risorse della macchina, ma suppongo che sia più veloce della forzatura brutale attraverso LINQ e foreach.

Problemi correlati