给定现有哈希,例如:
{
"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 :(得分: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 :(得分: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}