ruby openclassroom - Comment trouver une clé de hachage contenant une valeur correspondante




tutorial apprendre (9)

Étant donné que j'ai le hash des clients ci-dessous, y a-t-il une manière rapide de ruby ​​(sans avoir à écrire un script multi-ligne) pour obtenir la clé donnée que je veux correspondre au 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"}
}

Answers

Ruby 1.9 et plus:

hash.key(value) => key

Ruby 1.8 :

Vous pouvez utiliser hash.index

hsh.index(value) => key

Renvoie la clé pour une valeur donnée. Si non trouvé, renvoie nil .

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

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

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

Vous pouvez utiliser hashname.key (valuename)

Ou, une inversion peut être dans l'ordre. new_hash = hashname.invert vous donnera un new_hash qui vous permet de faire les choses plus traditionnellement.


De la docs:

  • (Object?) Detect (ifnone = nil) {| obj | ...}
  • (Objet?) Find (ifnone = nil) {| obj | ...}
  • (Object) detect (ifnone = nul)
  • (Object) find (ifnone = nul)

Passer chaque entrée dans enum à bloquer. Renvoie le premier pour lequel le bloc n'est pas faux. Si aucun objet ne correspond, appelle ifnone et renvoie son résultat quand il est spécifié, ou renvoie zéro sinon.

Si aucun bloc n'est donné, un énumérateur est renvoyé à la place.

(1..10).detect  {|i| i % 5 == 0 and i % 7 == 0 }   #=> nil
(1..100).detect {|i| i % 5 == 0 and i % 7 == 0 }   #=> 35

Cela a fonctionné pour moi:

clients.detect{|client| client.last['client_id'] == '2180' } #=> ["orange", {"client_id"=>"2180"}] 

clients.detect{|client| client.last['client_id'] == '999999' } #=> nil 

Voir: http://rubydoc.info/stdlib/core/1.9.2/Enumerable#find-instance_method



La meilleure façon de trouver la clé pour une valeur particulière est d'utiliser la méthode clé qui est disponible pour un hachage ....

gender = {"MALE" => 1, "FEMALE" => 2}
gender.key(1) #=> MALE

J'espère que cela résoudra votre problème ...


Une autre approche que j'essaierais est d'utiliser #map

clients.map{ |key, _| key if clients[key] == {"client_id"=>"2180"} }.compact 
#=> ["orange"]

Cela retournera toutes les occurrences de valeur donnée. Le trait de soulignement signifie que nous n'avons pas besoin que la valeur de la clé soit transportée de sorte qu'elle ne soit pas affectée à une variable. Le tableau contiendra nils si les valeurs ne correspondent pas - c'est pourquoi j'ai mis #compact à la fin.


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


essaye ça:

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

J'ai toujours utilisé sort_by . Vous devez envelopper la sortie #sort_by avec Hash[] pour qu'il génère un hachage, sinon il sort un tableau de tableaux. Alternativement, pour accomplir ceci vous pouvez exécuter la méthode #to_h sur le tableau de tuples pour les convertir en une structure k=>v (hash).

hsh ={"a" => 1000, "b" => 10, "c" => 200000}
Hash[hsh.sort_by{|k,v| v}] #or hsh.sort_by{|k,v| v}.to_h

Il y a une question similaire dans " Comment trier un Ruby Hash par valeur numérique? ".





ruby