Comment rechercher dans un tableau de hachages par valeurs de hachage en rubis?


234

J'ai un tableau de hachages, @fathers.

a_father = { "father" => "Bob", "age" =>  40 }
@fathers << a_father
a_father = { "father" => "David", "age" =>  32 }
@fathers << a_father
a_father = { "father" => "Batman", "age" =>  50 }
@fathers << a_father 

Comment puis-je rechercher ce tableau et retourner un tableau de hachages pour lesquels un bloc retourne vrai?

Par exemple:

@fathers.some_method("age" > 35) #=> array containing the hashes of bob and batman

Merci.

Réponses:


419

Vous recherchez Enumerable # select (également appelé find_all):

@fathers.select {|father| father["age"] > 35 }
# => [ { "age" => 40, "father" => "Bob" },
#      { "age" => 50, "father" => "Batman" } ]

Selon la documentation, il "renvoie un tableau contenant tous les éléments de [l'énumérable, dans ce cas @fathers] pour lequel le bloc n'est pas faux."


22
Oh! Tu étais le premier! Suppression de ma réponse et +1.
Milan Novota, le

20
Remarque: si vous ne souhaitez en trouver qu'un seul (le premier), vous pouvez l'utiliser à la @fathers.find {|father| father["age"] > 35 }place.
Leigh McCulloch

1
Est-il possible de retourner l'index de l'endroit où cela a été trouvé dans le tableau d'origine des hachages?
Ian Warner du

1
@IanWarner Oui. Je suggère de regarder les documents du module Enumerable. Si vous ne parvenez toujours pas à le comprendre, postez une nouvelle question.
Jordan Running

Je viens de faire cet index = ARRAY.index {| h | h [: code] == TABLEAU ["code"]}
Ian Warner

198

cela retournera le premier match

@fathers.detect {|f| f["age"] > 35 }

6
Je préfère cela à #select- Mais tout va pour votre cas d'utilisation. #detectreviendra nilsi aucune correspondance n'est trouvée, tandis que #select, dans la réponse de @ Jordan, reviendra [].
TJ Biddle

13
Vous pouvez également utiliser findau lieu de detectpour un code plus lisible
Alter Lagos

8
findpeut toutefois prêter à confusion dans les rails.
user12341234

5
selectet detectne sont pas identiques, selecttraversera l'ensemble du tableau, tandis que detects'arrêtera dès que la première correspondance sera trouvée. SI vous cherchez UN match @fathers.select {|f| f["age"] > 35 }.firstcontre @fathers.detect {|f| f["age"] > 35 } pour la performance et la lisibilité, mon vote va pourdetect
Naveed

35

si votre tableau ressemble

array = [
 {:name => "Hitesh" , :age => 27 , :place => "xyz"} ,
 {:name => "John" , :age => 26 , :place => "xtz"} ,
 {:name => "Anil" , :age => 26 , :place => "xsz"} 
]

Et vous voulez savoir si une valeur est déjà présente dans votre tableau. Utiliser la méthode Find

array.find {|x| x[:name] == "Hitesh"}

Cela retournera un objet si Hitesh est présent dans le nom sinon retourne nil


Si le nom était en minuscule "hitesh", il ne renverra pas le hachage. Comment pouvons-nous également tenir compte de la casse des mots dans de tels cas?
arjun

2
vous pouvez utiliser quelque chose comme. array.find {| x | x [: nom] .downcase == "Hitesh" .downcase}
Hitesh Ranaut
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.