38

我在使用 reduce 的语法时遇到问题。我有以下格式的哈希:

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

我想使用 reduce 来查找此函数中值的总和。

就像是

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

我知道这是错误的。我不明白如何使 elem 成为哈希值。

4

6 回答 6

80

您可以elem通过将其拆分为 2 个变量来包含该值:

H.reduce(0) {|memo, (key, val)| memo + val}
于 2012-12-14T17:17:54.967 回答
41

如果哈希恰好为空,请使用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
于 2012-12-14T16:58:49.957 回答
6

试试这个:

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

或者

H.reduce(0) { |memo, (key, value)| memo += value }
于 2012-12-14T16:58:43.903 回答
2

我知道我正在挖掘这个,但如果你碰巧使用 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现在可以使用.

于 2016-04-29T21:28:42.160 回答
1
h = {"Key1" => 1, "Key2" => 2}

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

或者

h.values.inject(:+)
# => 3
于 2012-12-14T16:56:26.610 回答
0

在复杂散列的情况下,首先将其映射到值数组可能更容易,然后减少:

values = H.map do |k, v|
    # some complex logic here
end
values.reduce(:+)

或者values.reduce(0, :+)如果数组可能为空。

于 2020-07-02T18:47:17.960 回答