240 votes

Comment trouver une clé de hachage contenant une valeur correspondante

Étant donné que j'ai le hash de clients ci-dessous, y a-t-il un moyen rapide en ruby (sans avoir à écrire un script sur plusieurs lignes) pour obtenir la clé que je veux correspondre à client_id ? Par exemple, comment obtenir la clé pour client_id == "2180" ?

clients = {
  "yellow"=>{"client_id"=>"2178"}, 
  "orange"=>{"client_id"=>"2180"}, 
  "red"=>{"client_id"=>"2179"}, 
  "blue"=>{"client_id"=>"2181"}
}

478voto

Aillyn Points 5955

Ruby 1.9 et supérieur :

hash.key(value) => key

Ruby 1.8 :

Vous pourriez utiliser hash.index

hsh.index(value) => key

Renvoie la clé pour une valeur donnée. Si elle n'est pas trouvée, renvoie nil.

h = { "a" => 100, "b" => 200 }
h.index(200) #=> "b"
h.index(999) #=> nil

Donc pour obtenir "orange", vous pourriez simplement utiliser :

clients.key({"client_id" => "2180"})

2 votes

Cela deviendrait un peu compliqué si les hashs avaient plusieurs clés, car vous auriez besoin de donner l'intégralité du hash à index.

55 votes

Le Hash#index est renommé en Hash#key en Ruby 1.9

14 votes

Notez que cela ne renvoie que la première correspondance, s'il y a plusieurs paires de hachage avec la même valeur, il renverra la première clé avec une valeur correspondante.

195voto

Daniel Vandersluis Points 30498

Vous pourriez utiliser Enumerable#select:

clients.select{|key, hash| hash["client_id"] == "2180" }
#=> [["orange", {"client_id"=>"2180"}]]

Notez que le résultat sera un tableau de toutes les valeurs correspondantes, dans lequel chacune est un tableau de la clé et de la valeur.

26 votes

@ Coderama La différence entre find et select est que find renvoie le premier match et select (qui est également appelé findAll) renvoie tous les matches.

0 votes

Je vois, donc ce serait l'option la plus sûre pour les cas où il y a plus d'une correspondance.

1 votes

C'est mieux que de créer un tout nouveau hash (en appelant invert) juste pour trouver un élément.

50voto

Peter DeWeese Points 10185

Vous pouvez inverser le hachage. clients.invert["client_id"=>"2180"] renvoie "orange"

3 votes

Cela semble aussi être une façon astucieuse (parce que c'est court) de le faire !

0 votes

Voici ce dont j'ai besoin pour les tableaux de formulaires (pour les listes déroulantes) qui créent un hash inversé

24voto

boulder_ruby Points 6257

Vous pourriez utiliser hashname.key(valuename)

Ou bien, une inversion peut être nécessaire. new_hash = hashname.invert vous donnera un new_hash qui vous permettra de faire les choses de manière plus traditionnelle.

3 votes

C'est la manière correcte de le faire dans les versions récentes (1.9+) de Ruby.

1 votes

#invert est une très mauvaise idée dans ce cas, car vous allouez essentiellement de la mémoire pour un objet de hachage jetable juste pour trouver une clé. Selon la taille du hachage, cela peut avoir un impact sérieux sur les performances

20voto

iNecas Points 522

Essayez ceci :

clients.find{|key,value| value["client_id"] == "2178"}.first

5 votes

Cela lancera une exception si la recherche renvoie nulle, car vous ne pouvez pas appeler .first sur nulle.

1 votes

Si vous utilisez Rails, vous pouvez utiliser .try(:first) au lieu de .first pour éviter les exceptions (si vous pensez qu'il est possible que la valeur soit manquante).

2 votes

Dans Ruby 2.3.0 +, vous pouvez utiliser le navigateur sécurisé &.first à la fin du bloc pour éviter une exception de Nil.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X