Sums of Columns

So, I pulled out data from Excel and saved them into array similar to this.

data = [['ABCD', 'EF', 4930, 326, 21023],
        ['ABCD', 'EF', 943, 21, 3032.01],
        ['ABCD', 'EF', 2234.39, 332.16, 203.1],
        ['ABCD', 'EF', 5944.8, 504.3, 30329.32]]

Now, I need to find the sum of all number columns. First I thought, sum of column 2, 3 and 4.

sums = []

(2..4).each { |n| sums << data.map { |col| col[n] }.reduce(&:+) }

# => [14052.189999999999, 1183.46, 54587.43]

Then I have to merge the result1 with another array of 2 blank elements in order to finish the sum row. Or I can do …

sums = []

(0..4).each { |n| sums << (n > 1 ? data.map { |col| col[n] }.reduce(&:+) : '') }

# => ["", "", 14052.189999999999, 1183.46, 54587.43]

It is done but it is very difficult to read.

Right be for I went to bed (I hate it when this happens), I thought I can do it differently. After a couple of trials and errors. I came up with this …

sums = []

data.transpose.each_with_index { |val, col| sums << (col < 2 ? '' : val.reduce(&:+)) }

# => ["", "", 14052.189999999999, 1183.46, 54587.43]

It might not look much different and even longer but it has one less curly braces, which is always better.


  1. I can round out the number with .round(2) but I have another method that does formatting of the number so there no need to round it here.