按键对哈希进行分组并对值求和
Posted
技术标签:
【中文标题】按键对哈希进行分组并对值求和【英文标题】:Group hashes by keys and sum the values 【发布时间】:2011-05-26 02:35:14 【问题描述】:我有一个哈希数组:
["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
【问题讨论】:
见***.com/q/4091487/322020 【参考方案1】: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
with a block 在找到重复时运行该块;没有初始memo
的inject
将数组的第一个元素视为memo
,这在这里很好。
【讨论】:
谢谢,这回答了问题,我不知道合并。非常感谢。 +1 这是 Ruby 书籍中必须包含的珠宝之一,但不是。 能不能解释一下这里的命名,memo和el是什么意思? @appleLovermemo
和 el
没有任何意义,你可以用任何词来交换它们。它们是变量名;我为memo =>I remember, el => element
选择了这些@
你能帮我理解这段代码吗,请提及 k、old_v、new_v 的值。我很困惑【参考方案2】:
简单使用:
array = ["Vegetable"=>10, "Vegetable"=>5, "Dry Goods"=>3, "Dry Goods"=>2]
array.inject|a,b| a.merge(b)|_,x,y| x + y
【讨论】:
感谢您为未使用的变量使用下划线 _【参考方案3】: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
【讨论】:
名副其实的丰富建议【参考方案4】:我不确定哈希是否是您想要的,因为我在每个哈希中没有多个条目。所以我先稍微改变一下你的数据表示。
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
【讨论】:
谢谢!我知道但需要真正弄脏的结构,我完全不知道各个方面。我添加了输出哈希的原始代码,因为我可能可以在那里做一些更简单的事情。【参考方案5】:如果有两个带有多个键的哈希:
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
【讨论】:
以上是关于按键对哈希进行分组并对值求和的主要内容,如果未能解决你的问题,请参考以下文章
Scala:如何按键分组并在 scala 中对值求和并以预期的返回类型返回列表
根据 pandas 中的字典对数据帧的行进行分组并对相应的分子求和