当前位置:  开发笔记 > 后端 > 正文

如何在Ruby中求和数组?

如何解决《如何在Ruby中求和数组?》经验,为你挑选了12个好方法。

我有一个整数数组.

例如:

array = [123,321,12389]

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

我知道

sum = 0
array.each { |a| sum+=a }

会工作.



1> 小智..:

或者尝试Ruby 1.9方式:

array.inject(0, :+)

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

> [].inject(:+)
nil
> [].inject(0, :+)
0


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

2> zenazn..:

试试这个:

array.inject(0){|sum,x| sum + x }

请参阅Ruby的可枚举文档

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


jorney的`array.inject(:+)`效率更高.
在rails中,array.sum`可能会给你数组值的总和.
在大多数情况下,我更喜欢使用`reduce`,它是`inject`的别名(如`array.reduce(:+)`).
`array.inject(:+)`似乎在Ruby 1.8.6中导致**麻烦**异常"LocalJumpError:no block given"可能会弹出.
@Boris此外,Rubycop会警告你使用`inject`而不是`reduce`.
@Peter,array.inject(:+)在空数组上返回nil!

3> Evan..:
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)


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

4> Mike Woodhou..:

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

require 'activesupport'
array.sum


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

5> jrhicks..:

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


Monkeypatching基类不是很好.

6> Eli Sadoff..:
Ruby 2.4.0的新功能

您可以使用恰当命名的方法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.



7> HashFail..:

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

array.inject(0){|sum,x| sum + x.amount}


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

8> collect..:

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今天发布,其中包含此功能!

9> Vova..:

ruby 1.8.7方式如下:

array.inject(0, &:+) 



10> 小智..:

你可以简单地使用:

    example = [1,2,3]
    example.inject(:+)



11> Santhosh..:

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



12> 小智..:

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

推荐阅读
k78283381
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有