2013-07-10 5 views
0

Я использую хэш хешей в Ruby, называемый MYMOVIES, как показано ниже.Хеш хэшей, как получить ключи от первого вложенного хэша

{"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"}} 

Теперь я хотел бы получить все ключи от первого вложенного хэша (т.е. названия, года, играет, ..., omdbapiurl).

Я попытался с:

mynestedhash = MYMOVIES.first 
    puts mynestedhash.keys.to_s 

Но я получаю ошибку:

undefined method `keys' for #<Array:0x801c56f8> (NoMethodError) 

Как я мог сделать?

ответ

2

Если все внутренние хэши имеют те же ключи, следующий будет достаточно

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 

Если ключи внутренних хэши могут быть разными, вы должны присоединиться к ним как Прити и toro2k в своих решениях.

+0

Отлично, спасибо большое! – MDT

1
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 

Выход

["title", 
"year", 
"plays", 
"last_played", 
"seen_date", 
"imdb_id", 
"rating", 
"omdbapiurl"] 

Теперь посмотрим, почему ваш код не работает ниже:

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/ 
#[] 

Теперь ясно, что из #grep метода, что массив не keys метод. Поэтому попробуйте приведенный выше код, чтобы сделать его работоспособным.

+0

Большое спасибо за полезное объяснение! – MDT

2

Это должно сделать:

MYMOVIES.map { |_, h| h.keys }.flatten.uniq 
# => ["title", "year", "plays", "last_played", "seen_date", "imdb_id", "rating", "omdbapiurl"] 

Ваш код не работает, так как метод first возвращает массив, а не хэш:

MYMOVIES.first 
# => ["127 Hours", {"title"=>"127 Hours", ... }]] 

Update Если вы хотите, чтобы получить ключи из первого хеша, то вы можете сделать:

nested_hash = MYMOVIES.first[1] 
nested_hash.keys 
# => ["title", "year", "plays", "last_played", "seen_date", "imdb_id", "rating", "omdbapiurl"] 

Или же:

_, nested_hash = MYMOVIES.first 
nested_hash.keys 
# => ["title", "year", "plays", "last_played", "seen_date", "imdb_id", "rating", "omdbapiurl"] 
+0

Да, но не существует способа вернуть хэш из хэша (так как я создал его как хэш хэша!)? mytmplist = {} mytmplist [ 'название'] = "" mytmplist [ 'год'] = "" mytmplist [ 'играет'] = 1 mytmplist [ 'last_played'] = mytimestamp mytmplist [ 'seen_date' ] = myformattedseendate mytmplist [ 'imdb_id'] = "" mytmplist [ 'оценка'] = "" mytmplist [ 'omdbapiurl'] = "" MyMovies [MovieTitle] = "" – MDT

+2

@MDT Что вы попросили в этом посте был дан ответ. Теперь, если у вас есть другая потребность, опубликуйте его в другом вопросе. Из комментария это не читается, что вы ищете. –

+0

'mytmplist = {} mytmplist [ 'название'] = "" mytmplist [ 'год'] = "" mytmplist [ 'играет'] = 1 mytmplist [ 'last_played'] = mytimestamp mytmplist [ 'seen_date' ] = myformattedseendate mytmplist [ 'imdb_id'] = "" mytmplist [ 'оценка'] = "" mytmplist [ 'omdbapiurl'] = "" MyMovies [MovieTitle] = mytmplist' Вот что я хотел отправить, извините за нечитаемое сообщение раньше и большое спасибо за ваш полезный ответ. – MDT