Answers:
array.inject(:+)
效率更高。
array.inject(:+)
似乎在Ruby 1.8.6中引起麻烦。可能会弹出“ LocalJumpError:未提供任何块”。
array.sum
可能会给您数组值的总和。
reduce
,这是的别名inject
(如array.reduce( :+ )
)。
inject
而不是reduce
。
或者尝试使用Ruby 1.9:
array.inject(0, :+)
注意:0
需要基本情况,否则nil
将在空数组上返回:
> [].inject(:+)
nil
> [].inject(0, :+)
0
array.map(&:price).inject(0, :+)
比较安全。它确保如果您有一个空列表,则得到0而不是nil。
array.inject(0) { |sum, product| sum += product.price }
array.reduce(0, :+)
虽然等同array.inject(0, :+)
,但随着MapReduce编程模型的兴起,减少一词进入了一个更为普遍的说法。
注入,缩小,折叠,累积和压缩都是一类折叠函数的同义词。我发现在您的代码库中保持一致性是最重要的,但是由于各个社区倾向于优先使用一个单词而不是另一个单词,因此了解替代方法还是很有用的。
为了强调map-reduce语言,这里提供了一个版本,该版本对该数组中的最终内容略加宽容。
array.map(&:to_i).reduce(0, :+)
一些其他相关阅读:
reduce
可以进一步告诉我该功能的作用,但inject
听起来确实要酷得多。
reduce
和map
更高阶的功能早的MapReduce。灵感是另一种方式。在MapReduce的意义上,它与简单的功能缩减有所不同,对不同机器的通信方式有影响。
或者(仅作比较),如果您安装了Rails(实际上只是ActiveSupport):
require 'activesupport'
array.sum
require 'active_support/core_ext/enumerable.rb'
,或者需要所有活动的支持:require 'active_support/all'
。有关此信息的更多信息,请访问:API Docs
activesupport
是一个巨大的依赖关系拖入一个项目,从去array.inject(:+)
到array.sum
。
require 'active_support/core_ext/enumerable'
没有.rb
后缀,因为它是隐式添加的。
对于Ruby> = 2.4.0,可以使用sum
Enumerables。
[1, 2, 3, 4].sum
mokeypatch基类很危险。如果您喜欢危险并使用旧版本的Ruby,可以将其添加#sum
到Array
该类中:
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)
仅出于多样性的考虑,如果您的数组不是数字数组,而是具有数字(例如数量)属性的对象数组,也可以执行此操作:
array.inject(0){|sum,x| sum + x.amount}
array.map(&:amount).inject(0, :+)
。查看其他答案。
map
then inject
要求您循环遍历两次数组:一次创建一个新数组,另一次对成员求和。此方法稍微冗长一些,但也更有效。
您可以简单地使用:
example = [1,2,3]
example.inject(:+)
inject(:+)
但这不行inject :+
吗?
这就够了
[1,2,3].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].sum{|x| x * 2 } == 6
:
# http://madeofcode.com/posts/74-ruby-core-extension-array-sum
class Array
def sum(method = nil, &block)
if block_given?
raise ArgumentError, "You cannot pass a block and a method!" if method
inject(0) { |sum, i| sum + yield(i) }
elsif method
inject(0) { |sum, i| sum + i.send(method) }
else
inject(0) { |sum, i| sum + i }
end
end
end
如果您觉得高尔夫,可以
eval([123,321,12389]*?+)
这将创建一个字符串“ 123 + 321 + 12389”,然后使用函数eval进行求和。这仅是为了打高尔夫球,请勿在正确的代码中使用它。
方法1:
[1] pry(main)> [1,2,3,4].sum
=> 10
[2] pry(main)> [].sum
=> 0
[3] pry(main)> [1,2,3,5,nil].sum
TypeError: nil can't be coerced into Integer
方法2:
[24] pry(main)> [].inject(:+)
=> nil
[25] pry(main)> [].inject(0, :+)
=> 0
[4] pry(main)> [1,2,3,4,5].inject(0, :+)
=> 15
[5] pry(main)> [1,2,3,4,nil].inject(0, :+)
TypeError: nil can't be coerced into Integer
from (pry):5:in `+'
方法3:
[6] pry(main)> [1,2,3].reduce(:+)
=> 6
[9] pry(main)> [].reduce(:+)
=> nil
[7] pry(main)> [1,2,nil].reduce(:+)
TypeError: nil can't be coerced into Integer
from (pry):7:in `+'
方法4: 当Array包含nil和空值时,默认情况下,如果您使用上述任何函数reduce,sum,inject都会通过
TypeError:无法将nil强制转换为Integer
你可以克服这个
[16] pry(main)> sum = 0
=> 0
[17] pry(main)> [1,2,3,4,nil, ''].each{|a| sum+= a.to_i }
=> [1, 2, 3, 4, nil, ""]
[18] pry(main)> sum
=> 10
方法6: 评估
计算字符串中的Ruby表达式。
[26] pry(main)> a = [1,3,4,5]
=> [1, 3, 4, 5]
[27] pry(main)> eval a.join '+'
=> 13
[30] pry(main)> a = [1,3,4,5, nil]
=> [1, 3, 4, 5, nil]
[31] pry(main)> eval a.join '+'
SyntaxError: (eval):1: syntax error, unexpected end-of-input
1+3+4+5+
这是最短的方法。尝试一下。
array.inject :+
number = [1..100]
number. each do |n|
final_number = n.sum
puts "The sum is #{final_number}"
end
*这对我作为新开发人员来说非常有效。您可以通过更改[]中的值来调整数字范围
您也可以轻松地做到这一点
def sum(numbers)
return 0 if numbers.length < 1
result = 0
numbers.each { |num| result += num }
result
end
您可以像这样使用.map和.sum:
array.map { |e| e }.sum
array.sum
array.sum