I have a nested hashes in ruby and I need to access a specific value of it. My hash look like below.
hash =
{"list"=>
{"0"=>
{"date"=>"11/03/2014",
"item1"=>"",
"tiem2"=>"News",
"item3"=>"",
"item4"=>"",
"item5"=>"Videos",
"Type"=>"Clip"},
"1"=>
{"date"=>"11/03/2014",
"item1"=>"",
"tiem2"=>"News",
"item3"=>"",
"item4"=>"",
"item5"=>"Videos",
"Type"=>"Program"}
}}
I need to access the value of "Type" of each keys. I tried with the below code but I am not sure why it didn't work.
hash_type = hash["list"].keys.each {|key| puts key["Type"]}
But it returned the list of keys. ie 0 and 1
Please help.
hash["list"].map {|_, hash| hash['Type']}
Explanation:
hash = {key: 'value'}
You can loop over a hash using each
like this:
hash.each {|pair| puts pair.inspect } #=> [:key, 'value']
or like this
hash.each {|key, value| puts "#{key}: #{value}"} #=> key: value
Since we don't use key anywhere, some of the IDEs will complain about unused local variable key
. To prevent this it is ruby convention to use _
for variable name and all the IDEs will not care for it to be unused.
hash['list'].collect { |_, value| value['Type'] }
=> ["Clip", "Program"]
This is following your logic (some answers posted different ways to do this). The reason why you go things wrong, if we go step by step is:
hash_type = hash["list"].keys #=> ["0", "1"]
So everything after that is the same like:
["0", "1"].each {|key| puts key["Type"]}
So you're basically doing puts '1'['Type']
and '0'['Type']
which both evaluate to nil
(try it in IRB) . Try replacing the puts
with p
and you'll get nil printed 2 times. The reason why you're getting hash_type
to be ["0", "1"] is because your last expression is keys.each
and each
ALWAYS return the "receiver", that is the array on which you called each
(as we saw earlier, that array is ["0", "1"]).
The key to solving this, following your particular logic, is to put the "keys" (which are '0' and '1' in this instance) in the appropriate context , and putting them in a context would look something like this:
hash_type = hash["list"].keys.each {|key| puts hash["list"][key]["Type"]}`
This will print the keys. However, hash_type will still be ["0", "1"] (remember, each
returns the value of the receiver). If you want the actual type values to be stored in hash_types, replace each
with map
and remove puts
:
hash_type = hash["list"].keys.map {|key| hash["list"][key]["Type"]} #=> ["Clip", "Program"]
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.