我有一个数组如下:
[[172, 3],
[173, 1],
[174, 2],
[174, 3],
[174, 1]]
我希望转换为数组,但是在对匹配键的值进行求和时。所以我得到以下内容:
{172 => 3, 173 => 1, 174 => 6}
我将如何做到这一点?
答案 0 :(得分:7)
我将如何做到这一点?
一次解决一个问题。
鉴于你的数组:
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
Bummer,这不起作用,因为哈希的值最初是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}
看起来不错。我们甚至可以使用each_with_object
:
a.each_with_object(Hash.new(0)) { |(k, v), h| h[k] += v }
#=> {172=>3, 173=>1, 174=>6}
答案 1 :(得分:3)
您可以尝试一下:
> 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}
答案 2 :(得分:1)
有关:
bcprov-jdk15on-1.47
您可以使用默认值为0的哈希
array = [[172, 3], [173, 1], [174, 2], [174, 3], [174, 1]]
然后使用它,并总结值:
hash = Hash.new{|h,k| h[k] = 0 }
答案 3 :(得分:1)
另一种可能的解决方案:
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}