如何在Ruby中求和数组?

时间:2009-10-08 16:04:58

标签: ruby arrays math sum

我有一个整数数组。

例如:

array = [123,321,12389]

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

我知道,

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

会起作用。

23 个答案:

答案 0 :(得分:790)

或尝试Ruby 1.9方式:

array.inject(0, :+)

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

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

答案 1 :(得分:589)

试试这个:

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

See Ruby's Enumerable Documentation

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

答案 2 :(得分:277)

array.reduce(0, :+)

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

注入减少弃牌累积压缩都是同义为folding functions的一类。我发现代码库中的一致性最重要,但由于各个社区倾向于选择一个词而不是另一个词,因此了解替代词仍然很有用。

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

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

一些额外的相关阅读:

答案 3 :(得分:109)

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

require 'activesupport'
array.sum

答案 4 :(得分:55)

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

[1, 2, 3, 4].sum

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

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

答案 5 :(得分:36)

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

答案 6 :(得分:19)

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

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

答案 7 :(得分:18)

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

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

*注意:#sum方法是enumerable 2.4的新增功能,因此您现在可以在纯红宝石中使用array.sum,而不仅仅是Rails。

答案 8 :(得分:18)

ruby​​ 1.8.7方式如下:

array.inject(0, &:+) 

答案 9 :(得分:16)

您可以简单地使用:

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

答案 10 :(得分:5)

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

答案 11 :(得分:4)

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 :(得分:3)

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

答案 13 :(得分:3)

对于具有nil值的数组,我们可以做紧凑,然后注入总和 前 -

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

答案 14 :(得分:2)

array.reduce(:+)

适用于范围 ...... 因此,

(1..10).reduce(:+) returns 55

答案 15 :(得分:1)

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

eval([123,321,12389]*?+)

这将创建一个字符串“123 + 321 + 12389”,然后使用函数eval来完成总和。 仅用于高尔夫目的,不应在正确的代码中使用它。

答案 16 :(得分:0)

或者您可以尝试这种方法:

def sum arr
  0 if arr.empty
  arr.inject :+
end

答案 17 :(得分:0)

这是最短的方式。试试吧。

array.inject :+

答案 18 :(得分:0)

方法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,注入一切都将通过

  

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:       的 EVAL

以字符串形式评估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+

答案 19 :(得分:0)

number = [1..100]

number. each do |n|

    final_number = n.sum

    puts "The sum is #{final_number}"
end

*作为新开发人员,这对我来说效果很好。您可以通过更改[]

中的值来调整数字范围

答案 20 :(得分:0)

3种求和数组的方法

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

2)array.inject('+')

3)array.join('+')

答案 21 :(得分:-1)

您也可以轻松完成

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

答案 22 :(得分:-8)

您可以使用 .map .sum ,如:

array.map { |e| e }.sum