2016-10-05 3 views
-1

Учитывая существующий хеш, такие как:Fetch ключи существующей хэш и дать им значения по умолчанию

{ 
    "April_data" : { 
    "April" : 10, 
    "May" : 8, 
    "June" : 7, 
    "July" : 7, 
    "August" : 5, 
    "September" : 2 
    }, 
    "May_data" : { 
    "May" : 4, 
    "June" : 3, 
    "July" : 2, 
    "August" : 2, 
    "September" : 0 
    }, 
    "June_data" : { 
    "June" : 12, 
    "July" : 12, 
    "August" : 8, 
    "September" : 2 
    } 
} 

Как я могу действовать, чтобы сохранить все ключи, содержащиеся в «April_data» в другие месяцы и присваивает значения по умолчанию например, «0»? Таким образом, результат будет выглядеть следующим образом:

{ 
    "April_data" : { 
    "April" : 10, 
    "May" : 8, 
    "June" : 7, 
    "July" : 7, 
    "August" : 5, 
    "September" : 2 
    }, 
    "May_data" : { 
    "April": 0, 
    "May" : 4, 
    "June" : 3, 
    "July" : 2, 
    "August" : 2, 
    "September" : 0 
    }, 
    "June_data" : { 
    "April": 0, 
    "May": 0, 
    "June" : 12, 
    "July" : 12, 
    "August" : 8, 
    "September" : 2 
    } 
} 

Любая помощь apreciated

+0

Добро пожаловать на Stack Overflow. Пожалуйста, прочитайте «[ask]», включая связанные страницы, и «[mcve]». Также «[Насколько ожидаются усилия по исследованию пользователей Stack Overflow?] (Http://meta.stackoverflow.com/a/261593/128421)». Мы хотим знать, какие усилия вы приложили для решения проблемы. Вы искали сайты и не нашли ответы? Если да, то где и как эти страницы не смогли ответить на вопрос? Вы писали код? Если нет, то почему? Если да, то где минимальный пример, демонстрирующий проблему? Без этого похоже, что вы хотите, чтобы мы записали код для вас. –

ответ

2
stub = hash.each_with_object({}) do |(_, v), memo| 
    memo.merge!(v) 
end.map { |k, v| [k, 0] } # or end.keys.product([0]).to_h 
    .to_h 
#⇒ {"April"=>0, "May"=>0, "June"=>0, "July"=>0, "August"=>0, "September"=>0} 

hash.map { |k, v| [k, stub.merge(v)] }.to_h 
#⇒ desired result 
1

Хитрость заключается в том, чтобы помнить, что хэши будет перезаписывать существующие ключи, поэтому начните с по умолчанию и наложения их на те, которые вы хотите держать:

DEFAULTS = { 
    "April" => 0, 
    "May" => 0, 
    "June" => 0, 
    "July" => 0, 
    "August" => 0, 
    "September" => 0 
} 

data = { 
    "April_data" => { 
    "April" => 10, 
    "May" => 8, 
    "June" => 7, 
    "July" => 7, 
    "August" => 5, 
    "September" => 2 
    }, 
    "May_data" => { 
    "May" => 4, 
    "June" => 3, 
    "July" => 2, 
    "August" => 2, 
    "September" => 0 
    }, 
    "June_data" => { 
    "June" => 12, 
    "July" => 12, 
    "August" => 8, 
    "September" => 2 
    } 
} 

data.each do |k, v| 
    data[k] = DEFAULTS.merge(v) 
end 

Какие результаты в:

require 'ap' 
ap data 

# >> { 
# >> "April_data" => { 
# >>  "April"  => 10, 
# >>  "May"  => 8, 
# >>  "June"  => 7, 
# >>  "July"  => 7, 
# >>  "August" => 5, 
# >>  "September" => 2 
# >> }, 
# >> "May_data" => { 
# >>  "April"  => 0, 
# >>  "May"  => 4, 
# >>  "June"  => 3, 
# >>  "July"  => 2, 
# >>  "August" => 2, 
# >>  "September" => 0 
# >> }, 
# >> "June_data" => { 
# >>  "April"  => 0, 
# >>  "May"  => 0, 
# >>  "June"  => 12, 
# >>  "July"  => 12, 
# >>  "August" => 8, 
# >>  "September" => 2 
# >> } 
# >> } 

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

DEFAULTS = data.flat_map{ |k, v| v.keys}.uniq.map{ |k| [k, 0] }.to_h 
# => {"April"=>0, "May"=>0, "June"=>0, "July"=>0, "August"=>0, "September"=>0} 

Вот что это делает:

DEFAULTS = data 
      .flat_map{ |k, v| v.keys} # => ["April", "May", "June", "July", "August", "September", "May", "June", "July", "August", "September", "June", "July", "August", "September"] 
      .uniq # => ["April", "May", "June", "July", "August", "September"] 
      .map{ |k| [k, 0] } # => [["April", 0], ["May", 0], ["June", 0], ["July", 0], ["August", 0], ["September", 0]] 
      .to_h 
# => {"April"=>0, "May"=>0, "June"=>0, "July"=>0, "August"=>0, "September"=>0} 

в качестве альтернативы, но не обязательно быстрее или более кратким:

DEFAULTS = data.values # => [{"April"=>10, "May"=>8, "June"=>7, "July"=>7, "August"=>5, "September"=>2}, {"May"=>4, "June"=>3, "July"=>2, "August"=>2, "September"=>0}, {"June"=>12, "July"=>12, "August"=>8, "September"=>2}] 
       .flat_map(&:keys) # => ["April", "May", "June", "July", "August", "September", "May", "June", "July", "August", "September", "June", "July", "August", "September"] 
       .uniq # => ["April", "May", "June", "July", "August", "September"] 
       .map{ |k| [k, 0] }.to_h # => {"April"=>0, "May"=>0, "June"=>0, "July"=>0, "August"=>0, "September"=>0} 
Смежные вопросы