ruby:将两个或多个数组的相应成员相加

jjn*_*vis 38 ruby arrays sum

我有两个(或更多)数组,每个数组有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]
Run Code Online (Sandbox Code Playgroud)

有没有更好的方法呢?这似乎是一件非常基本的事情.

gle*_*ald 50

这是transposeAnurag建议的版本:

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

这适用于任意数量的组件阵列.reduce并且inject是同义词,但reduce在我看来更清楚地传达代码的意图......

  • @jjnevis:好吧,如果我们打高尔夫球,那么`a.transpose.map(&:sum)怎么样? (6认同)
  • @jjnevis:所以,`Symbol#to_proc`返回一个`Proc`,它将该符号传递给它的参数(所以`:sum.to_proc`返回`lambda {| x | x.sum}`).方法的最后一个参数的`&`前缀运算符在参数上调用`#to_proc`,并将生成的`Proc`作为块传递给方法.这允许你编写捕获它们的块参数的方法(`def foo(a,b,&block)... end`)并将它们传递给它们可以调用的任何方法(`bar = baz(1,&block)`).它还允许使用符号的这种技巧,因为`a.transpose.map(&:sum)`相当于你的rails解决方案. (4认同)

Abd*_*bdo 9

为了更清晰的语法(不是最快),您可以使用Vector:

require 'matrix'
Vector[1,2,3] + Vector[4,5,6]
=> Vector[5, 7, 9]
Run Code Online (Sandbox Code Playgroud)

对于多个向量,您可以:

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

如果您希望将数组加载到Vectors并求和:

arrays = [ [1,2,3], [4,5,6], [7,8,9] ]
arrays.map { |a| Vector[*a] }.inject(:+)
=> Vector[12, 15, 18]
Run Code Online (Sandbox Code Playgroud)


Anu*_*rag 7

这是我尝试代码打高尔夫球的事情:

// 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]
Run Code Online (Sandbox Code Playgroud)

zip返回[1,4],[2,5],[3,6],和地图总和每个子阵列.

  • 说'aoa`是我们的数组数组,你要计算`[aoa [0] [0] + aoa [1] [0] + ... + aoa [-1] [0],aoa [0] [1] + aoa [1] [1] + ... + aoa [-1] [1],...,aoa [0] [ - 1] + aoa [1] [ - 1] + ... + aoa [-1] [ - 1]]`然后你可以做'先,*休息=*aoa; first.zip(*rest).map {| a | a.inject(&:+)}` (2认同)
  • 我认为`arr.zip(arr).map {| a,b | a + b}`比使用2个元素数组上的inject/reduce更具可读性. (2认同)

小智 6

我谦卑地觉得我看到的其他答案非常复杂,以至于他们会让代码审稿人感到困惑.您需要添加一个解释性注释,这只会增加所需的文本量.

怎么回事:

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

稍微不同的解决方案:(这样你就不会硬编码"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] }
Run Code Online (Sandbox Code Playgroud)

最后,从数学上讲,这是同一个问题:

如何在Ruby中执行向量添加?


小智 6

现在我们可以在2.4中使用sum

nums = [[1, 2, 3], [4, 5, 6]]
nums.transpose.map(&:sum) #=> [5, 7, 9]
Run Code Online (Sandbox Code Playgroud)


小智 5

[[1,2,3],[4,5,6]].transpose.map{|a| a.sum} #=> [5,7,9]
Run Code Online (Sandbox Code Playgroud)

  • 请注意,这在纯Ruby中不起作用.也许它在Rails中,[由jjnevis建议](http://stackoverflow.com/questions/2682411/ruby-sum-corresponding-members-of-two-arrays#comment2702699_2682983). (2认同)