Ruby 求和值时要散列的数组

Ruby 求和值时要散列的数组,ruby,Ruby,我有一个数组,如下所示: [[172, 3], [173, 1], [174, 2], [174, 3], [174, 1]] 我想转换成一个数组,但同时求和匹配键的值。因此,我得到以下信息: {172 => 3, 173 => 1, 174 => 6} 我该怎么做呢?您可以尝试以下方法: > array #=> [[172, 3], [173, 1], [174, 2], [174, 3], [174, 1]] array.group_by(

我有一个数组,如下所示:

[[172, 3], 
 [173, 1], 
 [174, 2], 
 [174, 3], 
 [174, 1]]
我想转换成一个数组,但同时求和匹配键的值。因此,我得到以下信息:

{172 => 3, 173 => 1, 174 => 6}

我该怎么做呢?

您可以尝试以下方法:

> array
#=> [[172, 3], [173, 1], [174, 2], [174, 3], [174, 1]]

array.group_by(&:first).map { |k, v| [k, v.map(&:last).inject(:+)] }.to_h
#=> => {172=>3, 173=>1, 174=>6}
Ruby 2.4.0版本:

a.group_by(&:first).transform_values { |e| e.sum(&:last) }
#=> => {172=>3, 173=>1, 174=>6}
用于:

您可以使用默认值为0的哈希,如下所示

hash = Hash.new{|h,k| h[k] = 0 }
然后使用它,并将值相加:

array.each { |a, b| hash[a] += b }

#=> {172=>3, 173=>1, 174=>6}

另一种可能的解决办法:

arr = [[172, 3], [173, 1], [174, 2], [174, 3], [174, 1]]

hash = arr.each_with_object({}) {|a,h| h[a[0]] = h[a[0]].to_i + a[1]}

p hash
# {172=>3, 173=>1, 174=>6}
我该怎么做呢

一次解决一个问题

考虑到您的阵列:

a = [[172, 3], [173, 1], [174, 2], [174, 3], [174, 1]]
我们需要一个额外的哈希:

h = {}
然后我们必须遍历数组中的对:

a.each do |k, v|
  if h.key?(k) # If the hash already contains the key
    h[k] += v  # we add v to the existing value
  else         # otherwise
    h[k] = v   # we use v as the initial value
  end
end

h #=> {172=>3, 173=>1, 174=>6}
现在让我们重构它。条件语句看起来有点麻烦,如果我们只添加所有内容呢

h = {}
a.each { |k, v| h[k] += v }
#=> NoMethodError: undefined method `+' for nil:NilClass
糟糕,这不起作用,因为散列的值最初是
nil
。让我们解决这个问题:

h = Hash.new(0) # <- hash with default values of 0
a.each { |k, v| h[k] += v }
h #=> {172=>3, 173=>1, 174=>6}

转换_值
是在2.4中引入的?我一定是忽略了。非常有用!:-)@Stefan yeap,在2.4.0中:)哇,你甚至通过不起作用的部分来展示推理+1欢迎使用堆栈溢出。请阅读“”和“”以及链接页面。第一件事是我们需要看到你努力的证据。如果没有这一点,看起来你没有试图让我们为你做这件事。
h = Hash.new(0) # <- hash with default values of 0
a.each { |k, v| h[k] += v }
h #=> {172=>3, 173=>1, 174=>6}
a.each_with_object(Hash.new(0)) { |(k, v), h| h[k] += v }
#=> {172=>3, 173=>1, 174=>6}