我有一系列哈希:
[{"Vegetable"=>10}, {"Vegetable"=>5}, {"Dry Goods"=>3>}, {"Dry Goods"=>2}]
我想在这里使用inject
,但我确实在苦苦挣扎。
我想要一个反映前一个哈希重复键总和的新哈希:
[{"Vegetable"=>15}, {"Dry Goods"=>5}]
我控制输出此哈希的代码,以便我可以在必要时修改它。结果主要是哈希值,因为这可能会最终嵌套任意数量的级别,然后很容易在数组上调用flatten但不会平滑哈希的键/值:
def recipe_pl(parent_percentage=nil)
ingredients.collect do |i|
recipe_total = i.recipe.recipeable.total_cost
recipe_percentage = i.ingredient_cost / recipe_total
if i.ingredientable.is_a?(Purchaseitem)
if parent_percentage.nil?
{i.ingredientable.plclass => recipe_percentage}
else
sub_percentage = recipe_percentage * parent_percentage
{i.ingredientable.plclass => sub_percentage}
end
else
i.ingredientable.recipe_pl(recipe_percentage)
end
end
end
答案 0 :(得分:84)
ar = [{"Vegetable"=>10}, {"Vegetable"=>5}, {"Dry Goods"=>3}, {"Dry Goods"=>2}]
p ar.inject{|memo, el| memo.merge( el ){|k, old_v, new_v| old_v + new_v}}
#=> {"Vegetable"=>15, "Dry Goods"=>5}
带有块的 Hash.merge
在找到重复时运行块;没有初始inject
的{{1}}会将数组的第一个元素视为memo
,这里没问题。
答案 1 :(得分:11)
只需使用:
array = [{"Vegetable"=>10}, {"Vegetable"=>5}, {"Dry Goods"=>3}, {"Dry Goods"=>2}]
array.inject{|a,b| a.merge(b){|_,x,y| x + y}}
答案 2 :(得分:8)
ar = [{"Vegetable"=>10}, {"Vegetable"=>5}, {"Dry Goods"=>3}, {"Dry Goods"=>2}]
虽然Hash.merge
技术运行良好,但我认为inject
的效果更好:
ar.inject({}) { |memo, subhash| subhash.each { |prod, value| memo[prod] ||= 0 ; memo[prod] += value } ; memo }
=> {"Dry Goods"=>5, "Vegetable"=>15}
更好的是,如果您使用默认值为0的Hash.new
:
ar.inject(Hash.new(0)) { |memo, subhash| subhash.each { |prod, value| memo[prod] += value } ; memo }
=> {"Dry Goods"=>5, "Vegetable"=>15}
或者如果inject
让你的头受伤:
result = Hash.new(0)
ar.each { |subhash| subhash.each { |prod, value| result[prod] += value } }
result
=> {"Dry Goods"=>5, "Vegetable"=>15}
答案 3 :(得分:3)
我不确定哈希是你想要的,因为我在每个哈希中没有多个条目。所以我首先要稍微改变你的数据表示。
ProductCount=Struct.new(:name,:count)
data = [ProductCount.new("Vegetable",10),
ProductCount.new("Vegetable",5),
ProductCount.new("Dry Goods",3),
ProductCount.new("Dry Goods",2)]
如果散列可以有多个键值对,那么您可能想要做的是
data = [{"Vegetable"=>10}, {"Vegetable"=>5}, {"Dry Goods"=>3>}, {"Dry Goods"=>2}]
data = data.map{|h| h.map{|k,v| ProductCount.new(k,v)}}.flatten
现在使用facets gem如下
require 'facets'
data.group_by(&:name).update_values{|x| x.map(&:count).sum}
结果是
{"Dry Goods"=>5, "Vegetable"=>15}
答案 4 :(得分:3)
如果有两个具有多个键的哈希值:
h1 = { "Vegetable" => 10, "Dry Goods" => 2 }
h2 = { "Dry Goods" => 3, "Vegetable" => 5 }
details = {}
(h1.keys | h2.keys).each do |key|
details[key] = h1[key].to_i + h2[key].to_i
end
details