2009-06-12 14 views
5

Gibt es eine einfache Möglichkeit, den Durchschnitt eines Attributs in einer Sammlung zu erhalten?Ruby on Rails Feld Durchschnitt?

Zum Beispiel hat jeder Benutzer eine Punktzahl.

Bei einer Sammlung von Benutzern (@users), wie erhalten Sie die durchschnittliche Punktzahl für die Gruppe?

Gibt es etwas wie @ users.average (: score)? Ich glaube, ich stieß auf so etwas wie dies für Datenbankfelder, aber ich brauche es für eine Sammlung zu arbeiten ...

Antwort

12

Für Ihre Frage könnte man tatsächlich tun:

@users.collect(&:score).sum.to_f/@users.length if @users.length > 0 

Früher dachte ich, @users .collect (&: score). Durchschnitt hätte funktioniert. Für Datenbankfelder funktioniert User.average (: score). Sie können auch Folgendes hinzufügen: Bedingungen wie andere ActiveRecord-Abfragen.

+0

Sehr schön. Was macht der & in &: Score? – David

+0

Der Ampersand-Operator ist ein Ersatz für: @ users.collect {| user | user.score} Lesen Sie mehr darüber im Internet: http://eli.thegreenplace.net/2006/04/18/understanding-ruby-blocks-procs-and-methods/ –

+0

ziemlich genial. –

2

Ich benutze unseren Freund Array mit dieser Methode zu erweitern:

class Array 
    # Calculates average of anything that responds to :"+" and :to_f 
    def avg 
    blank? and 0.0 or sum.to_f/size 
    end 
end 
2

Hier ein kleiner Ausschnitt ist nur den Durchschnitt nicht erhalten, sondern auch die Standardabweichung.

class User 
    attr_accessor :score 
    def initialize(score) 
    @score = score 
    end 
end 

@users=[User.new(10), User.new(20), User.new(30), User.new(40)] 

[email protected](0){|acc, user| acc + user.score}/@users.length.to_f 
stddev = Math.sqrt(@users.inject(0) { |sum, u| sum + (u.score - mean) ** 2 }/@users.length.to_f)