2010-03-14 23 views
254

Duplicar posible:
Getting key of value of a generic Dictionary?obtener la clave de diccionario por valor

¿Cómo consigo una llave Diccionario de valor en C#?

Dictionary<string, string> types = new Dictionary<string, string>() 
{ 
      {"1", "one"}, 
      {"2", "two"}, 
      {"3", "three"} 
}; 

Quiero algo como esto:

getByValueKey(string value); 

getByValueKey("one") debe ser de vuelta "1".

¿Cuál es la mejor manera de hacerlo? ¿Tal vez HashTable, SortedLists?

+7

Duplicado exacto: http://stackoverflow.com/questions/255341/ – Gabe

+0

He leído este artículo antes, pero la respuesta llega. – loviji

+3

Sí, pero ahí obtienes [una respuesta aceptada de Skeet] (http://stackoverflow.com/a/255638/1028230). – ruffin

Respuesta

441

Los valores no necesariamente tienen que ser únicos, por lo que debe hacer una búsqueda. Se puede hacer algo como esto:

var myKey = types.FirstOrDefault(x => x.Value == "one").Key; 

Si los valores son únicos y se insertan con menos frecuencia que leer, a continuación, crear un diccionario inverso donde los valores son claves y las claves son valores.

+0

mis valores no están duplicados. entonces tu idea es buena para mí Gracias. – loviji

+2

@loviji: tenga en cuenta que en la solución de bucle, si el valor está al final del diccionario, tendrá que pasar por encima de todos los otros valores para encontrarlo. Si tiene varias entradas, esto ralentizará su programa. –

+2

@Zach Johnson: Gracias. Estoy de acuerdo contigo. y tu respuesta también me gusta. pero en mi diccionario 8-10 entradas. y no se agregan dinámicamente. y creo, usando esta respuesta no está mal solución. – loviji

21

Se podría hacer eso:

  1. Por bucle a través de todos los KeyValuePair<TKey, TValue> 's en el diccionario (que será un impacto de rendimiento considerable si tiene un número de entradas en el diccionario)
  2. Use dos diccionarios, uno para asignación de valor a clave y otro para asignación de clave a valor (que ocuparía el doble de espacio en la memoria).

Utilice el método 1 si el rendimiento no es una consideración, utilice el método 2 si la memoria no es una consideración.

Además, todas las claves deben ser únicas, pero no es necesario que los valores sean únicos. Puede tener más de una clave con el valor especificado.

¿Hay alguna razón por la que no puede revertir la relación clave-valor?

+0

Para crear el diccionario inverso programáticamente, todavía tendríamos que usar el método 1, ¿verdad? –

8

¿Qué pasa si el valor existe para más de una clave?

¿Qué tecla debe devolverse?

Para evitar hacer suposiciones Microsoft no ha incluido un método GetKey.

-8

Tengo una manera muy simple de hacer esto. Funcionó perfecto para mí.

Dictionary<string, string> types = new Dictionary<string, string>(); 

types.Add("1", "one"); 
types.Add("2", "two"); 
types.Add("3", "three"); 

Console.WriteLine("Please type a key to show its value: "); 
string rLine = Console.ReadLine(); 

if(types.ContainsKey(rLine)) 
{ 
    string value_For_Key = types[rLine]; 
    Console.WriteLine("Value for " + rLine + " is" + value_For_Key); 
} 
+2

Lo sentimos, pero su respuesta no cumple con la pregunta. La pregunta era cómo encontrar la clave por el valor, su respuesta muestra el estándar: encontrar el valor con la clave – Breeze

+1

Leer la primera pregunta, la próxima vez – Tommix

+2

Y esto, señoras y señores, es exactamente por qué leemos las preguntas antes de publicar una respuesta . – Krythic

-2
types.Values.ToList().IndexOf("one"); 

Values.ToList() convierte los valores del diccionario en una lista de objetos. IndexOf ("uno") busca su nueva Lista buscando "uno" y devuelve el índice que coincidiría con el índice del par clave/valor en el diccionario.

Este método no se preocupa por las teclas del diccionario, simplemente devuelve el índice del valor que está buscando.

Tenga en cuenta que puede haber más de un "uno" valor en su diccionario. Y esa es la razón por la cual no hay un método de "obtener clave".

-2

A continuación código sólo funciona si contiene único valor de datos

public string getKey(string Value) 
{ 
    if (dictionary.ContainsValue(Value)) 
    { 
     var ListValueData=new List<string>(); 
     var ListKeyData = new List<string>(); 

     var Values = dictionary.Values; 
     var Keys = dictionary.Keys; 

     foreach (var item in Values) 
     { 
      ListValueData.Add(item); 
     } 

     var ValueIndex = ListValueData.IndexOf(Value); 
     foreach (var item in Keys) 
     { 
      ListKeyData.Add(item); 
     } 

     return ListKeyData[ValueIndex]; 

    } 
    return string.Empty; 
} 
+1

-1 Demasiado código para un rendimiento que será peor que la [respuesta superior de Kimi] (https://stackoverflow.com/a/2444064/146513) (que se publicó 6 años antes que el tuyo). No necesita forzar las propiedades de las Llaves y los Valores para crear esas 2 listas (la Lista de Tareas de Linq lo hará por usted).Además, si va a usar IndexOf, podría haber evitado la llamada a ContainsValue (evitando así 2 bucles a través de todos los elementos para la misma tarea). –

+1

El rendimiento de esta sugerencia es simplemente horrible. También podría crear una clase genérica con dos diccionarios. Uno de los cuales contiene Key1 y Key2, y el otro que contiene Key2 y Key1. De esta forma, puede obtener cualquier clave sin ... bueno ... todo lo que su respuesta sugirió. – Krythic

-1

tal vez algo como esto:

foreach (var keyvaluepair in dict) 
{ 
    if(Object.ReferenceEquals(keyvaluepair.Value, searchedObject)) 
    { 
     //dict.Remove(keyvaluepair.Key); 
     break; 
    } 
} 
1

yo estaba en una situación en la que la unión no estaba disponible LINQ y tuvo que ampliar lambda explícita . El resultado fue una función simple:

public static string KeyByValue(Dictionary<string, string> dict, string val) 
{ 
    string key = null; 
    foreach (KeyValuePair<string, string> pair in dict) 
    { 
     if (pair.Value == val) 
     { 
      key = pair.Key; 
      break; 
     } 
    } 
    return key; 
} 

llamar así sigue:

public static void Main() 
{ 
    Dictionary<string, string> dict = new Dictionary<string, string>() 
    { 
     {"1", "one"}, 
     {"2", "two"}, 
     {"3", "three"} 
    }; 

    string key = KeyByValue(dict, "two");  
    Console.WriteLine("Key: " + key); 
} 

Works en .NET 2.0 y en otros entornos limitados.

Cuestiones relacionadas