如何在Ruby中求和数组?

bra*_*fck 551 ruby arrays math sum

我有一个整数数组.

例如:

array = [123,321,12389]
Run Code Online (Sandbox Code Playgroud)

有什么好方法可以得到它们的总和吗?

我知道

sum = 0
array.each { |a| sum+=a }
Run Code Online (Sandbox Code Playgroud)

会工作.

小智 795

或者尝试Ruby 1.9方式:

array.inject(0, :+)
Run Code Online (Sandbox Code Playgroud)

注意:0需要基本情况​​,否则nil将在空数组上返回:

> [].inject(:+)
nil
> [].inject(0, :+)
0
Run Code Online (Sandbox Code Playgroud)

  • `array.map(&:price).inject(0,:+)`有点安全.它确保如果你有一个空列表,你得到**0**而不是**nil**. (99认同)
  • 使用array.map(...).inject(...)是低效的,你将遍历所有数据两次.尝试`array.inject(0){| sum,product | sum + = product.price}` (10认同)
  • 你可以使用map方法的类似技巧:array.map(&:price).inject(:+) (7认同)
  • 如何使用这种方式从对象中求和属性.我的数组[product1,product2]我想总结product1.price + product2.price.是否可以使用array.inject(:+)? (6认同)
  • @ everett1992,事实证明,甚至根本没有优化.分两个阶段做这件事对我来说一直比较快.https://gist.github.com/cameron-martin/b907ec43a9d8b9303bdc (3认同)

zen*_*azn 599

试试这个:

array.inject(0){|sum,x| sum + x }
Run Code Online (Sandbox Code Playgroud)

请参阅Ruby的可枚举文档

(注意:0需要基本情况​​,以便0在空数组上返回而不是nil)

  • jorney的`array.inject(:+)`效率更高. (310认同)
  • 在rails中,array.sum`可能会给你数组值的总和. (33认同)
  • 在大多数情况下,我更喜欢使用`reduce`,它是`inject`的别名(如`array.reduce(:+)`). (31认同)
  • `array.inject(:+)`似乎在Ruby 1.8.6中导致**麻烦**异常"LocalJumpError:no block given"可能会弹出. (3认同)
  • @Boris此外,Rubycop会警告你使用`inject`而不是`reduce`. (3认同)
  • @Peter,array.inject(:+)在空数组上返回nil! (3认同)
  • 我正在学习 Ruby。到了这里,我就像_reaaally_?Ruby 使用所有我经常忘记的方法并且没有 *sum* 方法? (2认同)

Eva*_*van 281

array.reduce(0, :+)
Run Code Online (Sandbox Code Playgroud)

虽然相当于array.inject(0, :+),但随着MapReduce编程模型的兴起,术语" reduce"正在进入一种更常见的语言.

注入,缩小,折叠,累积压缩都是一类折叠函数的同义词.我发现代码库的一致性最为重要,但由于各个社区倾向于选择一个词而不是另一个词,因此了解备选方案仍然很有用.

为了强调map-reduce verbiage,这里的版本对于该数组中最终的内容有点宽容.

array.map(&:to_i).reduce(0, :+)
Run Code Online (Sandbox Code Playgroud)

一些额外的相关阅读:

  • 我同意,`reduce`告诉我更多关于函数的功能,但`inject`听起来更酷. (10认同)

Mik*_*use 110

或者(仅用于比较),如果您安装了Rails(实际上只是ActiveSupport):

require 'activesupport'
array.sum
Run Code Online (Sandbox Code Playgroud)

  • 较新版本的activesupport默认情况下不会实际加载所有扩展.您只需要求和模块:`require'active_support/core_ext/enumerable.rb'`,或者需要所有主动支持:`require'active_support/all'`.有关它的更多信息:[API Docs](http://edgeguides.rubyonrails.org/active_support_core_extensions.html) (12认同)
  • 没关系,`activesupport`是一个*大规模*依赖项,可以拖入项目,从`array.inject(:+)`到`array.sum`. (2认同)

jrh*_*cks 61

mokeypatch基类是危险的,现在Ruby 2.4.0对Enumerables总结了它并不危险.如果你喜欢危险并使用旧版本的Ruby,你可以添加sum#sum类中:

[1, 2, 3, 4].sum
Run Code Online (Sandbox Code Playgroud)

然后做有趣的事情,如:

class Array
  def sum
    inject(0) { |sum, x| sum + x }
  end
end
Run Code Online (Sandbox Code Playgroud)

  • Monkeypatching基类不是很好. (12认同)
  • 他提出的观点是,你不需要为 Ruby >= 2.4 做 Monkey Patch,而且 Monkey 补丁是危险的,你现在可以对枚举进行本地求和,但还有一种方法可以向后移植该功能。 (2认同)

Eli*_*off 43

Ruby 2.4.0的新功能

您可以使用恰当命名的方法Enumerable#sum.它有很多优点,inject(:+)但最后也有一些重要的注意事项要阅读.

例子

范围

(1..100).sum
#=> 5050
Run Code Online (Sandbox Code Playgroud)

数组

[1, 2, 4, 9, 2, 3].sum
#=> 21

[1.9, 6.3, 20.3, 49.2].sum
#=> 77.7
Run Code Online (Sandbox Code Playgroud)

重要的提示

这种方法不等同于#inject(:+).例如

%w(a b c).inject(:+)
#=> "abc"
%w(a b c).sum
#=> TypeError: String can't be coerced into Integer
Run Code Online (Sandbox Code Playgroud)

也,

(1..1000000000).sum
#=> 500000000500000000 (execution time: less than 1s)
(1..1000000000).inject(:+)
#=> 500000000500000000 (execution time: upwards of a minute)
Run Code Online (Sandbox Code Playgroud)

有关为何如此的详细信息,请参阅此答案sum.


Has*_*ail 19

只是为了多样性,如果您的数组不是数字数组,而是具有数字属性(例如数量)的对象数组,您也可以这样做:

array.inject(0){|sum,x| sum + x.amount}
Run Code Online (Sandbox Code Playgroud)

  • 在某种程度上,是的.但是,使用`map`然后`inject`需要你循环遍历数组两次:一次创建一个新数组,另一次是对成员进行求和.这种方法稍微冗长,但也更有效. (4认同)
  • 这相当于:`array.map(&:amount).inject(0,:+)`.看到其他答案. (3认同)

col*_*ect 19

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 2.4.0今天发布,其中包含此功能! (2认同)

Vov*_*ova 18

ruby 1.8.7方式如下:

array.inject(0, &:+) 
Run Code Online (Sandbox Code Playgroud)


小智 16

你可以简单地使用:

    example = [1,2,3]
    example.inject(:+)
Run Code Online (Sandbox Code Playgroud)


San*_*osh 5

Ruby 2.4.0已发布,它具有Enumerable#sum方法。所以你可以做

array.sum
Run Code Online (Sandbox Code Playgroud)

来自文档的示例:

{ 1 => 10, 2 => 20 }.sum {|k, v| k * v }  #=> 50
(1..10).sum                               #=> 55
(1..10).sum {|v| v * 2 }                  #=> 110
Run Code Online (Sandbox Code Playgroud)


小智 5

这就够了 [1,2,3].inject('+')