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.