Как сложить массив чисел в Ruby? - PullRequest
546 голосов
/ 08 октября 2009

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

Например:

array = [123,321,12389]

Есть ли какой-нибудь хороший способ получить их сумму?

Я знаю, что

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

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

Ответы [ 22 ]

791 голосов
/ 08 октября 2009

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

array.inject(0, :+)

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

> [].inject(:+)
nil
> [].inject(0, :+)
0
593 голосов
/ 08 октября 2009

Попробуйте это:

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

См. Перечень документации Ruby

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

277 голосов
/ 14 декабря 2012
array.reduce(0, :+)

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

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

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

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

Некоторые дополнительные соответствующие чтения:

110 голосов
/ 08 октября 2009

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

require 'activesupport'
array.sum
57 голосов
/ 08 октября 2009

Для 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
36 голосов
/ 04 января 2017

Новое для 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 такой.

19 голосов
/ 24 июля 2013

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

array.inject(0){|sum,x| sum + x.amount}
18 голосов
/ 22 июня 2011

Рубин 1.8.7:

array.inject(0, &:+) 
18 голосов
/ 09 июня 2016

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.

16 голосов
/ 03 мая 2016

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

    example = [1,2,3]
    example.inject(:+)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...