tags:

views:

151

answers:

2

Hi,

I have an array of two dimensional Arrays. I want to create a new two dimensional array which finds the sum of these values in the 2D arrays.

Sum at x,y of new array = Sum at x,y of arr1 + Sum at x,y of arr2 + ....

|1,2,4| |1,1,1| |1,1,1| 
|2,4,6| |1,1,1| |1,1,1| 
|2,4,6| |1,1,1| |1,1,1| 
|2,4,6| |1,1,1| |1,1,1| 

Now adding the above two dimensional arrays will result in,

|3,4,6|
|4,6,8|
|4,6,8|
|4,6,8|

How to achieve this in Ruby (not in any other languages). I have written a method, but it looks very long and ugly.

+1  A: 

Assuming every array has the same dimensions, you could use the following code: (let me know if you want any of it explained)

# returns an array 
# where each element (x,y) 
# is the sum of all elements (x,y) from an arbitrary number of arrays

def sum_arrays *a
  arr = []
  a[0].each_index do |r|       # iterate through rows
    row = []
    a[0][r].each_index do |c|  # iterate through columns
      # get sum at these co-ordinates, and add to new row
      row << a.inject(0) { |sum,e| sum += e[r][c] }
    end
    arr << row  # add this row to new array
  end
  arr # return new array
end

# data you supplied:
x = [[1,2,4],[2,4,6],[2,4,6],[2,4,6]]
y = [[1,1,1],[1,1,1],[1,1,1],[1,1,1]]
z = [[1,1,1],[1,1,1],[1,1,1],[1,1,1]]       

print sum_arrays x,y,z
# => [[3,4,6],[4,6,8],[4,6,8],[4,6,8]]

Hope this helps!

Jeriko
Thank you Jerkio!
Bragboy
+4  A: 
require 'matrix'

Matrix[
  [1, 2, 4],
  [2, 4, 6],
  [2, 4, 6],
  [2, 4, 6]
] +

Matrix[
  [1, 1, 1],
  [1, 1, 1],
  [1, 1, 1],
  [1, 1, 1]
] +

Matrix[
  [1, 1, 1],
  [1, 1, 1],
  [1, 1, 1],
  [1, 1, 1]
]

# => Matrix[[3, 4, 6], [4, 6, 8], [4, 6, 8], [4, 6, 8]]

Or, if you want the same format as in @Jeriko's answer, i.e. returning an Array instead of a Matrix:

def sum_arrays(*a)
  return *a.map {|m| Matrix[*m] }.reduce(:+)
end

# data you supplied:
x = [[1, 2, 4], [2, 4, 6], [2, 4, 6], [2, 4, 6]]
y = [[1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1]]
z = [[1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1]]

p sum_arrays(x, y, z)
# => [[3, 4, 6], [4, 6, 8], [4, 6, 8], [4, 6, 8]]
Jörg W Mittag
Sweet!! Thank Jorg!
Bragboy