Reputation: 1659
I am using a hash of hashes in Ruby, called MYMOVIES
, as below.
{"127 Hours"=>
{"title"=>"127 Hours",
"year"=>"2010",
"plays"=>1,
"last_played"=>1300489200,
"seen_date"=>"19/3/2011",
"imdb_id"=>"tt1542344",
"rating"=>"6",
"omdbapiurl"=>"http://www.omdbapi.com/?t=127 Hours&y=2010"},
"Zombieland"=>
{"title"=>"Zombieland",
"year"=>"2009",
"plays"=>1,
"last_played"=>1290207600,
"seen_date"=>"20/11/2010",
"imdb_id"=>"tt1156398",
"rating"=>"7",
"omdbapiurl"=>"http://www.omdbapi.com/?t=Zombieland&y=2009"}}
Now, I would like to get all the keys of the first nested hash (i.e. title, year, plays, ..., omdbapiurl).
I tried with:
mynestedhash = MYMOVIES.first
puts mynestedhash.keys.to_s
But I get the error:
undefined method `keys' for #<Array:0x801c56f8> (NoMethodError)
How could I do?
Upvotes: 0
Views: 688
Reputation: 1278
If all inner hashes have the same keys, the following will suffice
first_outer_key, first_outer_value = MYMOVIES.first
first_inner_hash = first_outer_value # change name to show what we have
inner_keys = first_inner_hash.keys
If the keys of the inner hashes can be different, you should join them like Priti and toro2k did in their solutions.
Upvotes: 2
Reputation: 19230
This should do:
MYMOVIES.map { |_, h| h.keys }.flatten.uniq
# => ["title", "year", "plays", "last_played", "seen_date", "imdb_id", "rating", "omdbapiurl"]
Your code didn't work because the method first
returns an array, not a hash:
MYMOVIES.first
# => ["127 Hours", {"title"=>"127 Hours", ... }]]
Update If you want to get the keys of the first hash, then you could do:
nested_hash = MYMOVIES.first[1]
nested_hash.keys
# => ["title", "year", "plays", "last_played", "seen_date", "imdb_id", "rating", "omdbapiurl"]
Or alternatively:
_, nested_hash = MYMOVIES.first
nested_hash.keys
# => ["title", "year", "plays", "last_played", "seen_date", "imdb_id", "rating", "omdbapiurl"]
Upvotes: 2
Reputation: 118261
require 'pp'
h = {"127 Hours"=>
{"title"=>"127 Hours",
"year"=>"2010",
"plays"=>1,
"last_played"=>1300489200,
"seen_date"=>"19/3/2011",
"imdb_id"=>"tt1542344",
"rating"=>"6",
"omdbapiurl"=>"http://www.omdbapi.com/?t=127 Hours&y=2010"},
"Zombieland"=>
{"title"=>"Zombieland",
"year"=>"2009",
"plays"=>1,
"last_played"=>1290207600,
"seen_date"=>"20/11/2010",
"imdb_id"=>"tt1156398",
"rating"=>"7",
"omdbapiurl"=>"http://www.omdbapi.com/?t=Zombieland&y=2009"}}
pp h.flat_map{|k,v| v.keys}.uniq
Output
["title",
"year",
"plays",
"last_played",
"seen_date",
"imdb_id",
"rating",
"omdbapiurl"]
Now see why your code didn't work below :
h = {"127 Hours"=>
{"title"=>"127 Hours",
"year"=>"2010",
"plays"=>1,
"last_played"=>1300489200,
"seen_date"=>"19/3/2011",
"imdb_id"=>"tt1542344",
"rating"=>"6",
"omdbapiurl"=>"http://www.omdbapi.com/?t=127 Hours&y=2010"},
"Zombieland"=>
{"title"=>"Zombieland",
"year"=>"2009",
"plays"=>1,
"last_played"=>1290207600,
"seen_date"=>"20/11/2010",
"imdb_id"=>"tt1156398",
"rating"=>"7",
"omdbapiurl"=>"http://www.omdbapi.com/?t=Zombieland&y=2009"}}
h.first
#["127 Hours",
# {"title"=>"127 Hours",
# "year"=>"2010",
# "plays"=>1,
# "last_played"=>1300489200,
# "seen_date"=>"19/3/2011",
# "imdb_id"=>"tt1542344",
# "rating"=>"6",
# "omdbapiurl"=>"http://www.omdbapi.com/?t=127 Hours&y=2010"}]
p h.first.grep /keys/
#[]
Now it is clear that from #grep
method that Array don't have keys
method. So try the above code to make it workable.
Upvotes: 1