How do I search within an array of hashes by hash values in ruby?
Solution 1
You're looking for Enumerable#select (also called find_all
):
@fathers.select {|father| father["age"] > 35 }
# => [ { "age" => 40, "father" => "Bob" },
# { "age" => 50, "father" => "Batman" } ]
Per the documentation, it "returns an array containing all elements of [the enumerable, in this case @fathers
] for which block is not false."
Solution 2
this will return first match
@fathers.detect {|f| f["age"] > 35 }
Solution 3
if your array looks like
array = [
{:name => "Hitesh" , :age => 27 , :place => "xyz"} ,
{:name => "John" , :age => 26 , :place => "xtz"} ,
{:name => "Anil" , :age => 26 , :place => "xsz"}
]
And you Want To know if some value is already present in your array. Use Find Method
array.find {|x| x[:name] == "Hitesh"}
This will return object if Hitesh is present in name otherwise return nil
Solution 4
(Adding to previous answers (hope that helps someone):)
Age is simpler but in case of string and with ignoring case:
- Just to verify the presence:
@fathers.any? { |father| father[:name].casecmp("john") == 0 }
should work for any case in start or anywhere in the string i.e. for "John"
, "john"
or "JoHn"
and so on.
- To find first instance/index:
@fathers.find { |father| father[:name].casecmp("john") == 0 }
- To select all such indices:
@fathers.select { |father| father[:name].casecmp("john") == 0 }
Related videos on Youtube
doctororange
Updated on August 13, 2020Comments
-
doctororange almost 4 years
I have an array of hashes, @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
How can I search this array and return an array of hashes for which a block returns true?
For example:
@fathers.some_method("age" > 35) #=> array containing the hashes of bob and batman
Thanks.
-
ARK almost 4 yearsThis question is quite helpful but I couldn't stop wondering why would one need an array of @fathers :P
-
-
Milan Novota over 14 yearsOh! You were the first one! Deleting my answer and +1.
-
TJ Biddle almost 11 yearsI prefer this over
#select
- But all goes for your use case.#detect
will returnnil
if no match is found, while#select
, in @Jordan's answer, will return[]
. -
Alter Lagos over 10 yearsYou could also use
find
instead ofdetect
for a more readable code -
Leigh McCulloch about 10 yearsAs a note, if you wanted only to find a single one (the first one) you can use
@fathers.find {|father| father["age"] > 35 }
instead. -
user12341234 about 9 years
find
can get confusing in rails, however. -
Ian Warner over 7 yearsIs it possible to return the index of where this was found in the original array of hashes?
-
Jordan Running over 7 years@IanWarner Yes. I suggest looking at the docs for the Enumerable module. If you still can't figure it out, post a new question.
-
Ian Warner over 7 yearsI just did this index = ARRAY.index { | h | h[ :code ] == ARRAY[ "code" ] }
-
user1735921 over 7 yearswhat is the fastest way to find it using the unique hash value, with no condition, the condition is
father["unique_id"] == 35
and not>
and we use a unique id instead of age ? Any suggestions ? I wan to find out the the father with that id. -
Naveed almost 7 years
select
anddetect
aren't same,select
will transverse the whole array, whiledetect
will stop as soon as the first match is found. IF you're looking for ONE match@fathers.select {|f| f["age"] > 35 }.first
vs@fathers.detect {|f| f["age"] > 35 }
for performance and readability, my vote goes fordetect
-
arjun about 6 yearsIf the name was lowercase like
"hitesh"
, it wont return the hash. How can we account for word casing as well in such cases? -
Hitesh Ranaut about 6 yearsyou can use something like. array.find {|x| x[:name].downcase == "Hitesh".downcase }
-
ARK almost 4 years@arjun
array.any?{ |element| element[:name].casecmp("hitesh")==0 }
should work for any case in start or anywhere in the string i.e. for"Hitesh"
,"hitesh"
or"hiTeSh"
-
ARK almost 4 yearsactually check my answer: stackoverflow.com/a/63375479/10313894
-
netwire almost 3 years
find
is an alias fordetect
method