2010-03-14 7 views
254

Possible en double:
Getting key of value of a generic Dictionary?obtenir la clé dictionnaire en valeur

Comment puis-je obtenir une clé Dictionary valeur en C#?

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

Je veux quelque chose comme ceci:

getByValueKey(string value); 

getByValueKey("one") doit être de retour "1".

Quel est le meilleur moyen de le faire? Peut-être HashTable, SortedLists?

+7

Exact duplicate: http://stackoverflow.com/questions/255341/ – Gabe

+0

J'ai lu cet article avant, mais répondez-y. – loviji

+3

Oui, mais vous obtenez [une réponse acceptée de Skeet] (http://stackoverflow.com/a/255638/1028230). – ruffin

Répondre

441

Les valeurs ne doivent pas nécessairement être uniques, vous devez donc effectuer une recherche. Vous pouvez faire quelque chose comme ceci:

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

Si les valeurs sont uniques et sont insérées moins fréquemment que lire, puis créer un dictionnaire inverse où les valeurs sont les touches et les touches sont des valeurs.

+0

Mes valeurs ne sont pas dublées. donc ton idée est bonne pour moi. Merci. – loviji

+2

@loviji: Gardez à l'esprit que dans la solution de bouclage, si la valeur se trouve à la fin du dictionnaire, il faudra parcourir toutes les autres valeurs pour le trouver. Si vous avez un certain nombre d'entrées, cela ralentira votre programme. –

+2

@Zach Johnson: Merci. je suis d'accord avec toi. et ta réponse me plait aussi. mais dans mon dictionnaire 8-10 entrées. et ils ne sont pas ajoutés dynamiquement. et je pense, en utilisant cette réponse pas mauvaise solution. – loviji

21

Vous pouvez le faire:

  1. En boucle à travers tous les KeyValuePair<TKey, TValue> « s dans le dictionnaire (qui sera un succès non négligeable de performances si vous avez un certain nombre d'entrées dans le dictionnaire)
  2. Utilisez deux dictionnaires, un pour le mappage valeur-clé et un pour le mappage clé-valeur (qui occuperait deux fois plus d'espace en mémoire).

Utilisez la méthode 1 si les performances ne sont pas prises en compte, utilisez la méthode 2 si la mémoire n'est pas prise en compte.

De plus, toutes les clés doivent être uniques, mais les valeurs ne doivent pas forcément être uniques. Vous pouvez avoir plus d'une clé avec la valeur spécifiée.

Y a-t-il une raison pour laquelle vous ne pouvez pas inverser la relation valeur-clé?

+0

Afin de créer le dictionnaire inverse par programme, nous aurions encore besoin d'utiliser la méthode 1, non? –

8

Que faire si la valeur existe pour plusieurs clés?

Quelle clé doit être retournée?

Pour éviter de faire des suppositions, Microsoft n'a pas inclus une méthode GetKey.

-8

J'ai un moyen très simple de le faire. Cela a fonctionné parfaitement pour moi.

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

Désolé, mais votre réponse ne répond pas à la question. La question était sur la façon de trouver la clé par la valeur, votre réponse montre la norme: trouver la valeur par la clé – Breeze

+1

Lire la question d'abord, la prochaine fois – Tommix

+2

Et ceci, Mesdames et Messieurs, est exactement pourquoi nous lisons les questions avant de poster une réponse . – Krythic

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

Values.ToList() convertit vos valeurs du dictionnaire dans une liste d'objets. IndexOf ("one") recherche dans votre nouvelle liste "one" et renvoie l'index qui correspond à l'index de la paire clé/valeur dans le dictionnaire.

Cette méthode ne se soucie pas des clés du dictionnaire, elle renvoie simplement l'index de la valeur que vous recherchez.N'oubliez pas qu'il peut y avoir plus d'une valeur "un" dans votre dictionnaire. Et c'est la raison pour laquelle il n'y a pas de méthode "get key".

-2

Ci-dessous le code ne fonctionne que si elle contient unique Données de la valeur

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 Trop de code pour une performance qui sera pire que la [meilleure réponse de Kimi] (https://stackoverflow.com/a/2444064/146513) (qui a été posté 6 ans avant le vôtre). Vous n'avez pas besoin de foreach les propriétés Keys and Values ​​afin de créer ces 2 listes (ToList de Linq le fera pour vous).De plus, si vous allez utiliser IndexOf, vous auriez pu éviter l'appel de ContainsValue (évitant ainsi 2 boucles mais tous les éléments pour la même tâche). –

+1

La performance de cette suggestion est juste affreuse. Vous pourriez aussi bien créer une classe générique avec deux Dictionnaires. L'un contient Key1 et Key2, et l'autre contient Key2 et Key1. De cette façon, vous pouvez obtenir l'une ou l'autre des clés sans ... eh bien ... tout ce que votre réponse a suggéré. – Krythic

-1

peut-être quelque chose comme ceci:

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

J'étais dans une situation où Linq liaison n'était pas disponible et a dû étendre lambda explicitement . Il a donné lieu à une fonction 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; 
} 

appeler comme suit:

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 sur .NET 2.0 et dans d'autres environnements limités.

Questions connexes