Reduceの構文に問題があります。次の形式のハッシュがあります。
H = {"Key1" => 1, "Key2" => 2}
Reduceを使用して、この関数の値の合計を見つけたいです。
何かのようなもの
H.reduce(0) {|memo, elem| memo+=elem}
私はこれが間違っていることを知っています。私はelemをハッシュの値にする方法を理解していません。
使用する - 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
これがキックの簡単なベンチマークです。キー/値のペアの値ではなく、値だけを減らす方が少し速いように見えることに注意してください。
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
elem
に値を含めるには、値を2つの変数に分割します。
H.reduce(0) {|memo, (key, val)| memo += val}
これを試して:
H.reduce(0) { |memo, elem| memo += elem[1] }
または
H.reduce(0) { |memo, (key, value)| memo += value }
私はこれを発掘していることを知っていますが、たまたま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
が利用可能になりました 。
h = {"Key1" => 1, "Key2" => 2}
h.values.inject(0){|f,v| f += v.to_i }
# => 3
または
h.values.inject(:+)
# => 3