我有一个整数数组.
例如:
array = [123,321,12389]
有什么好方法可以得到它们的总和吗?
我知道
sum = 0 array.each { |a| sum+=a }
会工作.
或者尝试Ruby 1.9方式:
array.inject(0, :+)
注意:0
需要基本情况,否则nil
将在空数组上返回:
> [].inject(:+) nil > [].inject(0, :+) 0
试试这个:
array.inject(0){|sum,x| sum + x }
请参阅Ruby的可枚举文档
(注意:0
需要基本情况,以便0
在空数组上返回而不是nil
)
array.reduce(0, :+)
虽然相当于array.inject(0, :+)
,但随着MapReduce编程模型的兴起,术语" reduce"正在进入一种更常见的语言.
注入,缩小,折叠,累积和压缩都是一类折叠函数的同义词.我发现代码库的一致性最为重要,但由于各个社区倾向于选择一个词而不是另一个词,因此了解备选方案仍然很有用.
为了强调map-reduce verbiage,这里的版本对于该数组中最终的内容有点宽容.
array.map(&:to_i).reduce(0, :+)
一些额外的相关阅读:
http://ruby-doc.org/core-1.9.3/Enumerable.html#method-i-inject
http://en.wikipedia.org/wiki/MapReduce
http://en.wikipedia.org/wiki/Fold_(higher-order_function)
或者(仅用于比较),如果您安装了Rails(实际上只是ActiveSupport):
require 'activesupport' array.sum
mokeypatch基类是危险的,现在Ruby 2.4.0对Enumerables总结了它并不危险.如果你喜欢危险并使用旧版本的Ruby,你可以添加sum
到#sum
类中:
[1, 2, 3, 4].sum
然后做有趣的事情,如:
class Array def sum inject(0) { |sum, x| sum + x } end end
您可以使用恰当命名的方法Enumerable#sum
.它有很多优点,inject(:+)
但最后也有一些重要的注意事项要阅读.
(1..100).sum #=> 5050
[1, 2, 4, 9, 2, 3].sum #=> 21 [1.9, 6.3, 20.3, 49.2].sum #=> 77.7
这种方法不等同于#inject(:+)
.例如
%w(a b c).inject(:+) #=> "abc" %w(a b c).sum #=> TypeError: String can't be coerced into Integer
也,
(1..1000000000).sum #=> 500000000500000000 (execution time: less than 1s) (1..1000000000).inject(:+) #=> 500000000500000000 (execution time: upwards of a minute)
有关为何如此的详细信息,请参阅此答案sum
.
只是为了多样性,如果您的数组不是数字数组,而是具有数字属性(例如数量)的对象数组,您也可以这样做:
array.inject(0){|sum,x| sum + x.amount}
Ruby 2.4+/Rails - array.sum
即[1, 2, 3].sum # => 6
Ruby pre 2.4 - array.inject(:+)
或array.reduce(:+)
*注意:该#sum
方法是2.4的新增功能,enumerable
因此您现在可以array.sum
在纯红宝石中使用,而不仅仅是Rails.
ruby 1.8.7方式如下:
array.inject(0, &:+)
你可以简单地使用:
example = [1,2,3] example.inject(:+)
Ruby 2.4.0已发布,它具有Enumerable#sum方法。所以你可以做
array.sum
来自文档的示例:
{ 1 => 10, 2 => 20 }.sum {|k, v| k * v } #=> 50 (1..10).sum #=> 55 (1..10).sum {|v| v * 2 } #=> 110
这就够了
[1,2,3].inject('+')