ruby哈希中相同值的总和

ruby哈希中相同值的总和,ruby,hash,Ruby,Hash,大家好。 例如,我有杂烩 {-2=>"a", -1=>"c", 1=>"a", 3=>"a", 49=>"a", -43=>"ab", 5=>"ab"} 可以有相等的值。我的任务是对值相等的键求和。结果: {51=>"a", -1=>"c", -38=>"ab"} 我该怎么做 hash.group_by{|key,val| val} 结果很糟糕 hash = {-2=>"a", -1=>"c", 1=>"a",

大家好。 例如,我有杂烩

{-2=>"a", -1=>"c", 1=>"a", 3=>"a", 49=>"a", -43=>"ab", 5=>"ab"}
可以有相等的值。我的任务是对值相等的键求和。结果:

{51=>"a", -1=>"c", -38=>"ab"}
我该怎么做

hash.group_by{|key,val| val}
结果很糟糕

hash = {-2=>"a", -1=>"c", 1=>"a", 3=>"a", 49=>"a", -43=>"ab", 5=>"ab"}

hash.reduce({}) do |memo, (k,v)| 
  memo[v] ||= 0
  memo[v] += k
  memo
end.invert

# => {51=>"a", -1=>"c", -38=>"ab"}
reduce
-允许您通过迭代集合的值(在本例中为
hash
)来建立新值。有关更多信息,请参阅

invert
-交换散列的键和值。有关更多信息,请参阅

其他方法:

hash.reduce(Hash.new(0)) { |memo, (k,v)| memo[v] += k; memo }.invert
然后

但这将是疯狂的,因为它依赖于总和是唯一的。(回想一下,散列有唯一的键。)假设

然后


由于
-1=>“a”
-1=覆盖,你应该使用
每个带有对象的\u
,而不是使用两个语句
reduce
。是的,我陷入了我的困境:)另外,我知道这是OP似乎想要的,但是
invert
可以删除数据,如果有两个字符串具有相同的和。这值得注意!
{1=>“a”,2=>“a”,3=>“b”}
的预期结果是什么?{3=>“a”,3=>“b”}您的预期结果无效,不能有重复的键。
h = {-2=>"a", -1=>"c", 1=>"a", 3=>"a", 49=>"a", -43=>"ab", 5=>"ab"}
h.group_by(&:last).each_with_object({}) { |(k,v),h| h[v.map(&:first).sum] = k }
  #=> {51=>"a", -1=>"c", -38=>"ab"} 
h = {-54=>"a", -1=>"c", 1=>"a", 3=>"a", 49=>"a", -43=>"ab", 5=>"ab"}
h.group_by(&:last).each_with_object({}) { |(k,v),h| h[v.map(&:first).sum] = k }
  #=> {-1=>"c", -38=>"ab"} 
a = [[-2, "a"], [-1, "c"], [-1, "a"], [49, "a"], [-43, "ab"],  [5, "ab"]]
a.group_by(&:last).each_with_object({}) { |(e,ar),h| h[e] = ar.map(&:first).sum }
  #=> {"a"=>46, "c"=>-1, "ab"=>-38}
h.group_by(&:last)
  #=> {"a"=>[[-2, "a"], [1, "a"], [3, "a"], [49, "a"]],
  #    "c"=>[[-1, "c"]], "ab"=>[[-43, "ab"], [5, "ab"]]} 
v.reduce(0) { |t,(n,_)| t+n }