Ruby: сумма соответствующих членов двух или более массивов
У меня есть два (или более) массива с 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]
Есть ли лучший способ сделать это? Просто кажется, что это очень важно.
Ответы
Ответ 1
Здесь версия transpose
Анураг предложила:
[[1,2,3], [4,5,6]].transpose.map {|x| x.reduce(:+)}
Это будет работать с любым количеством составных массивов. reduce
и inject
являются синонимами, но reduce
мне кажется более четко сообщать о намерении кода здесь...
Ответ 2
вот моя попытка кодового игры в гольф:
// 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]
и отображает суммы каждого подматрица.
Ответ 3
Для более четкого синтаксиса (не самый быстрый) вы можете использовать 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]
Ответ 4
[[1,2,3],[4,5,6]].transpose.map{|a| a.sum} #=> [5,7,9]
Ответ 5
Я смиренно чувствую, что другие ответы, которые я вижу, настолько сложны, что они будут путать с рецензентами кода. Вам нужно будет добавить пояснительный комментарий, который просто увеличит количество требуемого текста.
Как это сделать:
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?
Ответ 6
Теперь мы можем использовать sum в 2.4
nums = [[1, 2, 3], [4, 5, 6]]
nums.transpose.map(&:sum) #=> [5, 7, 9]
Ответ 7
@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]
Ответ 8
Для:
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]
Ответ 9
Это может быть не лучший ответ, но он работает.
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]
Это может быть больше строк кода, чем другие ответы, но это, тем не менее, ответ