Подтвердить что ты не робот

Уменьшить значения хеша

У меня возникают проблемы с синтаксисом для уменьшения. У меня есть хэш следующего формата:

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

Я хотел бы использовать сокращение, чтобы найти сумму значений в этой функции.

Что-то вроде

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

Я знаю, что это неправильно. Я не понимаю, как я могу сделать elem значение хэша.

4b9b3361

Ответ 1

Используйте 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

Ответ 2

Вы можете сделать elem значение, разделив его на две переменные:

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

Ответ 3

Попробуйте следующее:

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

или

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

Ответ 4

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

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

или

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

Ответ 5

Я знаю, что я раскопал этот, но если вы используете Rails, .sum метод может помочь:

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 теперь доступен.