Ruby Core Extension: Array#sum
It always bugs me that there is no #sum method on Arrays in Ruby. It's pretty easy to make your own:
class Array
def sum
inject(0) { |sum, i| sum + i }
end
end
If you really want to be terse, you can use Symbol#to_proc:
class Array
def sum
inject(&:+)
# i.e. inject(&proc { |obj, *args| obj.send(:+, *args) })
end
end
You could even just skip Symbol#to_proc, and pass in the method name you want to call on each accumulation:
class Array
def sum
inject(:+)
# i.e. inject { |sum, i| sum.send(:+, i) }
end
end
However, I'm going to stick with the first version because I think it's clearer in the final implementation:
class Array
def sum(method = nil, &block)
if block_given?
raise ArgumentError, "You cannot pass a block and a method!" if method
inject(0) { |sum, i| sum + yield(i) }
elsif method
inject(0) { |sum, i| sum + i.send(method) }
else
inject(0) { |sum, i| sum + i }
end
end
end
This accepts no arguments, a method or a block. So, you can write things like:
>> [1,2,3].sum
=> 6
>> [1,2,3].sum(:to_f)
=> 6.0
>> [1,2,3].sum(&:to_f)
=> 6.0
>> [1,2,3].sum { |i| i+1 }
=> 9