Hash を使ったよくある集計
メモ。あるオブジェクトの集合があって、各オブジェクトの属性を集計したいとかそういう場合。
基本的に、Hash を使って、key-value 型でやればいい。
# -*- coding: utf-8 -*- if RUBY_VERSION < "1.8.7" require 'enumerator' end Club = Class.new do attr_reader :_id_ def self.find(*args) [new(1), new(2)] end def initialize(_id_) @_id_ = _id_ end end Student = Struct.new(:name, :age, :height, :club_id) students = %w[ largo forte regret arietta air ].enum_with_index.map do |name, offset| Student.new(name, 10 + offset * 2, 120 + offset * 5, offset % 2 + 1) end # Hash を使う total = { :age => 0, :height => 0, } students.each do |s| total[:age] += s.age total[:height] += s.height end total # => {:age=>70, :height=>650} # Club 単位での集計 total = {} Club.find(:all).each do |club| total[club._id_] = { :age => 0, :height => 0, } end students.each do |s| total[s.club_id][:age] += s.age total[s.club_id][:height] += s.height end total # => {1=>{:age=>42, :height=>390}, 2=>{:age=>28, :height=>260}} # 集計にStruct を使うというのもある。アクセサが使える total = Struct.new(:age, :height).new(0, 0) students.each do |s| total.age += s.age total.height += s.height end total.age # => 70 total.height # => 650