ruby: сумма соответствующих членов двух или более массивов - PullRequest
35 голосов
/ 21 апреля 2010

У меня есть два (или более) массива с 12 целыми числами в каждом (соответствуют значениям для каждого месяца). Все, что я хочу, это сложить их вместе, чтобы у меня был один массив с суммированными значениями для каждого месяца. Вот пример с тремя значениями: [1,2,3] и [4,5,6] => [5,7,9]

Лучшее, что я мог придумать, было:

[[1,2,3],[4,5,6]].transpose.map{|arr| arr.inject{|sum, element| sum+element}} #=> [5,7,9]

Есть ли лучший способ сделать это? Просто кажется, что так хочется сделать.

Ответы [ 9 ]

48 голосов
/ 21 апреля 2010

Вот версия transpose, предложенная Анурагом:

[[1,2,3], [4,5,6]].transpose.map {|x| x.reduce(:+)}

Это будет работать с любым количеством массивов компонентов. reduce и inject являются синонимами, но, мне кажется, reduce более четко сообщает о намерениях кода здесь ...

8 голосов
/ 09 февраля 2014

Для более ясного синтаксиса (не самого быстрого) вы можете использовать Vector:

require 'matrix'
Vector[1,2,3] + Vector[4,5,6]
=> Vector[5, 7, 9]

Для нескольких векторов вы можете сделать:

arr = [ Vector[1,2,3], Vector[4,5,6], Vector[7,8,9] ]
arr.inject(&:+)
=> Vector[12, 15, 18]

Если вы хотите загрузить свои массивы в векторы и сумма:

arrays = [ [1,2,3], [4,5,6], [7,8,9] ]
arrays.map { |a| Vector[*a] }.inject(:+)
=> Vector[12, 15, 18]
7 голосов
/ 21 апреля 2010

Вот моя попытка сыграть в эту игру:

// ruby 1.9 syntax, too bad they didn't add a sum() function afaik
[1,2,3].zip([4,5,6]).map {|a| a.inject(:+)} # [5,7,9]

zip возвращает [1,4], [2,5], [3,6], и для каждого подмассива отображается карта.

5 голосов
/ 27 февраля 2015

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

Как это вместо этого:

a_arr = [1,2,3]
b_arr = [4,5,6]
(0..2).map{ |i| a_arr[i] + b_arr[i] }

Немного другое решение: (так что вы не сложнокодирование «2»)

a_arr = [1,2,3]
b_arr = [4,5,6]
c_arr = []
a_arr.each_index { |i| c_arr[i] = a_arr[i] + b_arr[i] }

Наконец, математически говоря, это тот же вопрос, что и этот:

Как выполнить сложение векторов в Ruby?

5 голосов
/ 12 декабря 2013
[[1,2,3],[4,5,6]].transpose.map{|a| a.sum} #=> [5,7,9]
4 голосов
/ 15 июля 2017

Теперь мы можем использовать сумму в 2,4

nums = [[1, 2, 3], [4, 5, 6]]
nums.transpose.map(&:sum) #=> [5, 7, 9]
1 голос
/ 05 октября 2016

Для:

a = [1,2,3]
b = [4,5,6]

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

p a.zip(b).map{|v| v.reduce(:+) }
#=> [5, 7, 9]

Или, если вы уверены, что массивы a и b всегда будут иметь одинаковую длину:

p a.map.with_index { |v, i| v + b[i] }
#=> [5, 7, 9]
1 голос
/ 08 сентября 2014

@ FriendFX, вы правы относительно ответа @ user2061694.Для меня это работало только в среде Rails.Вы можете запустить его в обычном Ruby, если внесете следующие изменения ...

В IRB

[[0, 0, 0], [2, 2, 1], [1,3,4]].transpose.map {|a| a.inject(:+)}
 => [3, 5, 5]


[[1,2,3],[4,5,6]].transpose.map {|a| a.inject(:+)}
 => [5, 7, 9]
0 голосов
/ 29 сентября 2014

Возможно, это не лучший ответ, но он работает.

array_one = [1,2,3]
array_two = [4,5,6]
x = 0
array_three = []
while x < array_one.length
  array_three[x] = array_one[x] + array_two[x]
  x += 1
end

=>[5,7,9]

Это может быть больше строк кода, чем другие ответы, но, тем не менее, это ответ

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...