web-dev-qa-db-ja.com

ハッシュ値を減らす

Reduceの構文に問題があります。次の形式のハッシュがあります。

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

Reduceを使用して、この関数の値の合計を見つけたいです。

何かのようなもの

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

私はこれが間違っていることを知っています。私はelemをハッシュの値にする方法を理解していません。

30
richsoni

使用する - 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
32
maerics

elemに値を含めるには、値を2つの変数に分割します。

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

これを試して:

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

または

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

私はこれを発掘していることを知っていますが、たまたま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が利用可能になりました

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

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

または

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