如何在Ruby中对数组求和?

gopyfrb3  于 2022-09-21  发布在  Ruby
关注(0)|答案(16)|浏览(204)

我有一个整数数组。

例如:

array = [123,321,12389]

有什么好方法可以算出它们的总和吗?

我知道,那是

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

会奏效的。

zzwlnbp8

zzwlnbp81#

对于ruby>=2.4,可以使用sum

array.sum

对于ruby<2.4,可以使用inject

array.inject(0, :+)

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

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

bd1hkmkf2#

试试这个:

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

请参见Ruby的可枚举文档

(注:需要0基本用例,以便在空数组上返回0,而不是nil)

r9f1avp5

r9f1avp53#

array.reduce(0, :+)

虽然相当于array.inject(0, :+),但随着MapReduce programming models的增加,术语REDUTE进入了一个更常见的白话。

注入减少折叠累积压缩都是folding functions的同义词。我发现跨代码库的一致性是最重要的,但由于不同的社区倾向于偏爱一个词而不是另一个词,因此了解替代方案是很有用的。

为了强调map-Reduced的措辞,这里有一个版本,它对该数组中结束的内容更宽容一些。

array.map(&:to_i).reduce(0, :+)

一些其他相关阅读材料:

e5nqia27

e5nqia274#

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

require 'activesupport'
array.sum
f1tvaqid

f1tvaqid5#

对于Ruby>=2.4.0,您可以使用Enumerables中的sum

[1, 2, 3, 4].sum

Mokeypatch基类是危险的。如果您喜欢Danger并使用旧版本的Ruby,可以将#sum添加到Array类中:

class Array
  def sum
    inject(0) { |sum, x| sum + x }
  end
end
pcww981p

pcww981p6#

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为什么是这样的更多信息,请参见this answer

9rbhqvlz

9rbhqvlz7#

Ruby 2.4+/rails-array.sum[1, 2, 3].sum # => 6

Ruby Pre 2.4-array.inject(:+)array.reduce(:+)

  • 注意:#sum方法是对enumerable的2.4的新添加,因此您现在可以在纯Ruby中使用array.sum,而不仅仅是rails。
5us2dqdw

5us2dqdw8#

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

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

uwopmtnx9#

Ruby 1.8.7方式如下:

array.inject(0, &:+)
kcwpcxri

kcwpcxri10#

Ruby 2.4.0发布了,它有一个可枚举的#sum方法。所以你可以这样做

array.sum

文档中的示例:

{ 1 => 10, 2 => 20 }.sum {|k, v| k * v }  #=> 50
(1..10).sum                               #=> 55
(1..10).sum {|v| v * 2 }                  #=> 110
ffscu2ro

ffscu2ro11#

对于零值的数组,我们可以进行压缩,然后注入总和ex-

a = [1,2,3,4,5,12,23.45,nil,23,nil]
puts a.compact.inject(:+)
xjreopfe

xjreopfe12#

还允许[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
9udxz4iz

9udxz4iz13#

方法一:

[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

方法二:

[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 `+'

方法三:

[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:**当数组包含nil和空值时,默认情况下,如果使用上述函数中的任何一个,则将通过

TypeError:不能将Nil强制为整数

你可以通过以下方式克服这个问题,

[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

*方法六:评估

计算字符串中的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+
nr9pn0ug

nr9pn0ug14#

如果你觉得高尔夫球,你可以做

eval [123,321,12389]*?+

这将创建一个字符串“123+321+12389”,然后使用函数EVERA进行求和。这是仅用于高尔夫球,您不应该在正确的代码中使用它。

v6ylcynt

v6ylcynt15#

你也可以用一种简单的方法来做

def sum(numbers)
  return 0 if numbers.length < 1
  result = 0
  numbers.each { |num| result += num }
  result
end

相关问题