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.

doctororange
la source

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."

Jordan Running
la source
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 }
Naveed
la source
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

Hitesh Ranaut
la source
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