Как суммировать массив чисел в Ruby?

У меня есть массив целых чисел.

Например:

array = [123,321,12389]

Есть ли хороший способ получить их сумму?

Я знаю, что

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

будет работать.

Ответ 2

Или попробуйте Ruby 1.9:

array.inject(0, :+)

Примечание: необходим базовый регистр 0, иначе nil будет возвращен на пустые массивы:

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

Ответ 3

array.reduce(0, :+)

В то время как эквивалент array.inject(0, :+), термин уменьшить вводит более распространенный язык с ростом моделей программирования MapReduce.

добавить, уменьшить, свернуть, накапливать и сжать. синонимом как класс функций сгибания. Я считаю, что последовательность в вашей кодовой базе наиболее важна, но поскольку различные сообщества предпочитают одно слово над другим, тем не менее полезно знать альтернативы.

Чтобы подчеркнуть вербальную карту, уменьшающую карту, существует версия, которая немного более прощает то, что заканчивается в этом массиве.

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

Некоторое дополнительное релевантное чтение:

Ответ 4

Альтернативно (только для сравнения), если у вас установлена ​​Rails (фактически только ActiveSupport):

require 'activesupport'
array.sum

Ответ 5

Для 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

Ответ 6

Новое для Ruby 2.4.0

Вы можете использовать метод aptly named 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

Просто ради разнообразия вы также можете сделать это, если ваш массив не является массивом чисел, а скорее массивом объектов, которые имеют свойства, которые являются числами (например, количество):

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

Ответ 8

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

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

* Примечание. Метод #sum является новым дополнением к 2.4 для enumerable, поэтому теперь вы сможете использовать array.sum в чистом рубине, а не только в Rails.

Ответ 9

ruby ​​1.8.7 путь следующий:

array.inject(0, &:+) 

Ответ 10

Вы можете просто использовать:

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

Ответ 11

Этого достаточно [1,2,3].inject('+')

Ответ 12

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

Ответ 13

Также позволяет [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

Ответ 14

для массива с нулевыми значениями мы можем сделать компакт и затем ввести сумму ex-

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

Ответ 15

array.reduce(:+)

Работает для Диапазоны тоже... следовательно,

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

Ответ 16

Если вы чувствуете игру в гольф, вы можете сделать

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

Это создаст строку "123 + 321 + 12389", а затем воспользуемся функцией eval для выполнения суммы. Это только для игры в гольф, вы не должны использовать его в правильном коде.

Ответ 17

Вы также можете использовать рекурсию

def sum(array)
  array.length == 1 ? array.pop() : array.pop() + sum(array)
end

Если вы не хотите быть разрушительным, сделайте клон.

Ответ 18

Способ 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: если массив содержит ноль и пустые значения, по умолчанию, если вы используете любые из вышеперечисленных функций, уменьшить, суммировать, внедрить все будет через

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

Или вы можете попробовать этот метод:

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

Ответ 20

Это самый короткий путь. Попытайся.

array.inject :+

Ответ 21

number = [1..100]

number. each do |n|

    final_number = n.sum

    puts "The sum is #{final_number}"
end

* Это хорошо работает для меня, как нового разработчика. Вы можете настроить свой диапазон номеров, изменив значения в пределах []

Ответ 22

Вы также можете сделать это простым способом

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

Ответ 23

Вы можете использовать .map и .sum как:

array.map { |e| e }.sum