A little (more) syntactic sugar in Rails
Posted by trevor Mon, 12 Jun 2006 17:48:56 GMT
This little extension to Ruby’s Array class is making the rounds:
class Array
def sum
inject(0) { |m, v| m + v }
end
end
# Use it thusly:
[1,2,3,4,5].sum # => 15
Nice. But what if we want to sum a member of each array element, such as the ‘price_cents’ attribute on a bunch of ActiveRecord objects?
@order.line_items.collect {|x| x.price_cents}.sum
# or (my preference) using Symbol's to_proc method:
@order.line_items.collect(&:price_cents).sum
Even with the sugar that Symbol#to_proc adds, it’s just a bit… well, blech. We can do better:
class Array
def sum
if block_given?
inject(0) { |m, v| m + yield(v) }
else
inject(0) { |m, v| m + v }
end
end
end
# Now we can say:
@order.line_items.sum(&:price_cents)
That’s just so much clearer.
Update: a recent changeset in the rails trunk adds a ‘sum’ method to Enumerable. It’s different from what I present above in that it only works with a block – which is okay for me because that’s my main usage pattern anyhow.