2012-12-14 116 views
22

我遇到了reduce的語法問題。我有以下格式的哈希:減少散列值

H = {"Key1" => 1, "Key2" => 2} 

我想用減少查找值的總和此功能。

H.reduce(0) {|memo, elem| memo+=elem} 

我知道這是不對的。我不明白我可以如何使elem的哈希值。

+6

嘗試:H.values.reduce(:+) –

+0

謝謝!那就是訣竅 – richsoni

回答

27

使用Enumerable#reduce,如果你確定與獲得nil如果哈希恰好是空:

H.values.reduce(:+) # => 3 
Hash.new.values.reduce(:+) # => nil 

要安全地獲得0當哈希是空的,使用:

H.values.reduce(0) { |sum,x| sum + x } # or... 
H.reduce(0) { |sum,(key,val)| sum + val } # ...if you need to inspect the key 

這裏有一個快速的基準,踢。請注意,這似乎是稍快,從鍵/值對減少只是值,而不是值:由2個變量分裂它

       user  system  total  real 
H.values.reduce(:+)  4.510000 0.080000 4.590000 ( 4.595229) 
H.values.reduce(0) {...} 4.660000 0.080000 4.740000 ( 4.739708) 
H.reduce(0) {...}   5.160000 0.070000 5.230000 ( 5.241916) 
require 'benchmark' 

size = 1_000 
hash = Hash[* Array.new(size*2) { rand } ] 

N=10_000 
Benchmark.bm(24) do |x| 
    x.report('H.values.reduce(:+)')  { N.times { hash.dup.values.reduce(:+) } } 
    x.report('H.values.reduce(0) {...}') { N.times { hash.dup.values.reduce(0) { |sum,x| sum + x } } } 
    x.report('H.reduce(0) {...}')  { N.times { hash.dup.reduce(0) { |sum,(_,v)| sum + v } } } 
end 
+0

請注意,如果散列爲空,則不會返回0。您需要使用 –

1
h = {"Key1" => 1, "Key2" => 2} 

h.values.inject(0){|f,v| f += v.to_i } 
# => 3 

h.values.inject(:+) 
# => 3 
4

試試這個:

H.reduce(0) { |memo, elem| memo += elem[1] } 

H.reduce(0) { |memo, (key, value)| memo += value } 
+1

我會寫'備忘錄+值'來避免讓人們認爲更新'備忘錄'有幫助。 – lkuty

64

您可以elem包含值:

H.reduce(0) {|memo, (key, val)| memo += val} 
+10

+1以下的備忘錄版本,才能使用cool(key,val)proc arg語法! – maerics

+1

這是非常漂亮的。 – jturolla

+3

我會寫'備忘錄+ val'來避免讓人們認爲更新'備忘錄'有幫助。 – lkuty

1

我知道我在挖掘這一個,但如果你碰巧使用Rails的,該.sum method可以幫助:

H = {"Key1" => 1, "Key2" => 2} 
=> {"Key1"=>1, "Key2"=>2} 
> H.values.sum 
=> 3 

優點是,它在空哈希返回0

> {}.values.sum 
=> 0 
> {}.values.reduce(:+) 
=> nil 

我注意到它只是打字這樣的回答後,Rails的具體。我知道OP沒有添加Rails標籤,但我認爲它可能對停下來的人有用。

請注意,截至Ruby 2.4.0,.sum is now available

+1

'.sum'現在在Ruby 2中實現。4 [Enumerable#sum](https://ruby-doc.org/core-2.4.0/Enumerable.html#method-i-sum)。 – user3162553

+0

好的,我在回答中加了一個註釋,謝謝! – astorije