Ruby: Summing values in an Array

In my last blog post I illustrated a very simple usage of Ruby’s inject method (more specifically, Enumerable#inject) – summing the values in array.  In the comments Wayne Conrad pointed out that there is an even simpler way of doing this and it got me thinking – how many different ways can you sum the values in an array?

Let’s start with the simplest case – a plain loop.

def test_sum_with_loop
    array = [1, 2, 3, 4]
    sum = 0
    for i in 0...array.length do
        sum += array[i]
    end
    assert_equal(10, sum)
end

The way I’ve illustrated already is with the inject method.

def test_sum_with_inject
    array = [1, 2, 3, 4]
    assert_equal(10, array.inject { |result, element| result += element } )
end

If you’re using Ruby 1.9 you also get access to Symbol#to_proc (which was previously a helper in ActiveSupport) and you can do the following (please note, I haven’t tested it – I’m still using 1.8).

def test_sum_with_inject
    array = [1, 2, 3, 4]
    assert_equal(10, array.inject(:+) )
end

We can achieve the same with a block and the collect method.

def test_sum_with_block
    array = [1, 2, 3, 4]
    sum = 0
    array.each { |i| sum += i }
    assert_equal(10, sum)
end

We can also try to use a lambda, but as far as I can tell we will first need to extend the Array class to write an iterator that takes a lambda as a parameter.

class Array
    def iterate(code)
        self.each do |n|
            code.call(n)
        end
    end
end

def test_sum_with_lambda
    array = [1, 2, 3, 4]
    sum = 0
    array.iterate(lambda { |i| sum += i })
    assert_equal(10, sum)
end

Using this same iterator we can also pass a Proc.

def test_sum_with_proc
    array = [1, 2, 3, 4]
    sum = 0
    sum_array = Proc.new do |n|
        sum += n
    end
    array.iterate(sum_array)
    assert_equal(10, sum)
end

Pretty cool!  Obviously most of these examples are really convoluted, but I’m simply trying to explore the different ways of doing things.  If you can think of any other ways (convoluted or not) of doing this, leave a comment below.  If I’m doing something really stupid in any of the examples, please point it out – I’m obviously very new to Ruby.

Happy coding.