我有一個陣列如下:陣列哈希而求和值
[[172, 3],
[173, 1],
[174, 2],
[174, 3],
[174, 1]]
即我想轉換成一個數組,但同時匹配鍵求和的值。所以我會得到以下幾點:
{172 => 3, 173 => 1, 174 => 6}
我該怎麼做呢?
我有一個陣列如下:陣列哈希而求和值
[[172, 3],
[173, 1],
[174, 2],
[174, 3],
[174, 1]]
即我想轉換成一個數組,但同時匹配鍵求和的值。所以我會得到以下幾點:
{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
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 – Mark
你可以嘗試一些事情:
> 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}
'transform_values'是在2.4中引入的嗎?我一定忽略了它。很有用! :-) – Stefan
@Stefan yeap,在2.4.0 :) –
爲:
array = [[172, 3], [173, 1], [174, 2], [174, 3], [174, 1]]
你可以使用一個哈希用默認值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}
歡迎來到Stack Overflow。請閱讀「[問]」和「[mcve]」以及鏈接的頁面。首先,我們需要看到你的努力的證據。沒有它,看起來你沒有嘗試並希望我們爲你做。 –