tags:

views:

315

answers:

2

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 was:

[[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.

+2  A: 

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.

Anurag
Nice. How would this work with three or more arrays - I'm iterating over an unknown number of arrays, so the transpose works well because I can just push them into an empty array and transpose that. I love the ':+' syntax for inject (although not as good as a sum() method as you say, rails does add it, though)- not see that before, thanks.
jjnevis
zip is a method of Array, and it accepts any number of arrays as parameters. But I don't know how would you pass those if they were created dynamically. `transpose` seems like a better choice for that. Ruby generally covers many of the commonly used functions, but where is lacks, Rails comes to rescue!
Anurag
rampion
+4  A: 

Here's the transpose version Anurag suggested:

a.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...

glenn mcdonald
... or in rails: a.transpose.map {|x| x.sum}
jjnevis
rampion
jjnevis
rampion
glenn mcdonald