开发者

ruby: sum corresponding members of two or more arrays

开发者 https://www.devze.com 2022-12-27 11:25 出处:网络
I\'ve got two (or more) arrays with 12 integers in each (corresponding to values for each month). All I want is to add them together so that I\'ve got a single array with summed values for each month.

I've got two (or more) arrays with 12 integers in each (corresponding to values for each month). All I want is to add them together so that I've got a single array with summed values for each month. Here's an example with three values: [1,2,3] and [4,5,6] => [5,7,9]

The best I could come up with wa开发者_如何学运维s:

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

Is there a better way of doing this? It just seems such a basic thing to want to do.


Here's the transpose version Anurag suggested:

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

This will work with any number of component arrays. reduce and inject are synonyms, but reduce seems to me to more clearly communicate the code's intent here...


Now we can use sum in 2.4

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


For clearer syntax (not the fastest), you can make use of Vector:

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

For multiple vectors, you can do:

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

If you wish to load your arrays into Vectors and sum:

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


here's my attempt at code-golfing this thing:

// 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 returns [1,4], [2,5], [3,6], and map sums each sub-array.


I humbly feel that the other answers I see are so complex that they would be confusing to code reviewers. You would need to add an explanatory comment, which just increases the amount of text needed.

How about this instead:

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

Slightly different solution: (so that you're not hard coding the "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] }

Finally, mathematically speaking, this is the same question as this:

How do I perform vector addition in Ruby?


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


@FriendFX, you are correct about @user2061694 answer. It only worked in Rails environment for me. You can make it run in plain Ruby if you make the following changes...

In the 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]


For:

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

You could zip and then use reduce:

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

Or, if you're sure that array a and b will always be of equal length:

p a.map.with_index { |v, i| v + b[i] }
#=> [5, 7, 9]


This might not be the best answer but it works.

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]

This might be more lines of code than other answers, but it is an answer nonetheless

0

精彩评论

暂无评论...
验证码 换一张
取 消