2010-10-23 31 views
25

¿Cómo obtener la clave del diccionario utilizando el valor del diccionario?Obtener la clave del diccionario utilizando el valor del diccionario

al conseguir el valor utilizando la tecla de la siguiente manera:

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

dic.Add(1, "a"); 

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

Cómo hacer lo contrario?

+0

posible duplicado de [Obteniendo la clave de valor de un diccionario genérico?] (Http://stackoverflow.com/questions/255341/getting-key-of-value-of-a-generic-dictionary) – bluish

Respuesta

61

Un diccionario está realmente destinado a la búsqueda unidireccional desde Key-> Value.

Usted puede hacer el uso opuesta LINQ:

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

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

Darse cuenta de que puede haber varias claves con el mismo valor, por lo que cualquier búsqueda adecuada devolverá un conjunto de teclas (que es por qué existe el foreach arriba) .

+2

ack, beat yo por 35 segundos! :) –

+0

Voy a adivinar que esto es probablemente más rápido que una para cada uno a través de pares de valores clave, pero no es más rápido que invertir el diccionario en torno a ¿eh? Tendré que recurrir a la banca solo para ver por curiosidad, pero sería más rápido simplemente hacer que el diccionario sea diferente, ¿verdad? – user99999991

+1

@ user999999928 Esto es básicamente lo mismo que hacer un foreach a través del diccionario. Si vas a hacer muchas búsquedas, compilar un diccionario "invertido" (que requiere una recopilación de valor) haría que las búsquedas sean más rápidas, pero las inserciones/cambios deberían manejarse en ambos. –

21

Fuerza 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"). Clave; – cilerler

+1

que emitirá una excepción si no hay una clave con ese valor. ('FirstOrDefault' devuelve nulo, toma' .Key' of null) –

10

También puede utilizar el siguiente método de extensión para obtener la clave de diccionario por valor

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

el uso también es tan simple

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

+1) ya que zain le está diciendo una nueva forma de implementar esto a través de los Métodos de extensión. – Singleton

2

manera fácil para conseguir una clave:

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

y para las llaves múltiples:

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

Comprendo que esto es una vieja pregunta, pero quería añadir algo que pensé de.

Si sabe que solo habrá una clave para un valor y deberá buscar tanto el valor como la clave; puedes crear dos diccionarios separados. Uno con la clave original como la clave y el valor como el valor y el segundo con la clave como el valor y el valor como la clave.

Ahora una nota al margen sobre esto; consume más recursos de la máquina, pero supongo que es más rápido que fuerza bruta a través de LINQ y foreach.

Cuestiones relacionadas