Never been to DZone Snippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Generic 'sum' and 'mean' methods for Ruby arrays (See related posts)

class Array; def sum; inject( nil ) { |sum,x| sum ? sum+x : x }; end; end


It's class agnostic, so you can do this:

[1,2,3].sum              # => 6
['a','b','c'].sum        # => 'abc'
[['a'], ['b','c']].sum   # => ['a', 'b', 'c']


You can then add a 'mean' operator easily:

class Array; def mean; sum / size; end; end


mean only works for numbers though, of course, like so:

[1,2,1000].mean    # => 334


That said, if your class implements division, it'll also work!

Comments on this post

wmacura posts on Jun 09, 2006 at 14:24
Adding elements in an array:

eval arr.join('+')


Multiplying:

eval arr.join('*')


Nice and easy! :)
peter posts on Jun 10, 2006 at 01:14
That's a very cute solution, but totally open to abuse :) Clever thinking though!
asdfasdf58 posts on Aug 09, 2006 at 07:57
Wouldn't the following also work?

class Array; def sum; inject() { |sum,element| sum+element }; end; end


With no argument, the inject loop begins with the second element of the array in
element
, and the value of the first in
sum
.
chebuctonian posts on Sep 08, 2006 at 16:19
I adapted this to my Array class and added an extract method:
def extract(sym)
  map { |e| e.send(sym) }
end
def sum
  inject( 0 ) { |sum,x| sum+x }
end
def mean
  (size > 0) ? sum.to_f / size : 0
end


Because I find this pretty:
@reviews.extract(:stars).mean


It's totally unnecessary, and in a large team would lead to chaos. But damnit, it's my project :)
babelian posts on Feb 12, 2007 at 16:46
you probably want

def mean; sum.to_f / size; end


(added to_f) so that

[1,2].mean


produces 1.5 not 1
wiseleyb posts on Oct 03, 2007 at 16:55
#http://en.wikipedia.org/wiki/Mean#Weighted_arithmetic_mean
def weighted_arithmetic_mean(weights_array)
raise "Each element of the array must have an accompanying weight. Array length = #{self.size} versus Weights length = #{weights_array.size}" if weights_array.size != self.size
w_sum = weights_array.sum
w_prod = 0
self.each_index {|i| w_prod += self[i] * weights_array[i].to_f}
w_prod.to_f / w_sum.to_f
end

You need to create an account or log in to post comments to this site.


Click here to browse all 5140 code snippets

Related Posts