Skip to content

Instantly share code, notes, and snippets.

@fabiob
Created June 21, 2011 04:42
Show Gist options
  • Save fabiob/1037260 to your computer and use it in GitHub Desktop.
Save fabiob/1037260 to your computer and use it in GitHub Desktop.
class PivotTable
attr_accessor :table, :totals, :grand_total, :pivot_values
def initialize(options)
@data = options[:data]
@row_fields = options[:row_fields].to_a
@data_field = options[:data_field]
@pivot_field = options[:pivot_field]
@pivot_values = options[:pivot_values]
build_table
end
private
def build_table()
@table = []
@totals = {}
@grand_total = 0
@data.group_by {|r| @row_fields.map {|m| r.send(m)} }.each do |g, r|
h = {}
@row_fields.each_with_index { |field, i| h[field] = g[i] }
total = 0
vals = {}
@pivot_values.each do |v|
sum = r.
select { |t| t.send(@pivot_field) == v }.
map { |t| t.send(@data_field) }.
reduce(0) { |s, n| s + n.to_f }
h["#{@pivot_field}_#{clean v}"] = sum
vals[v] = sum
@totals[v] ||= 0
@totals[v] += sum || 0
@grand_total += sum || 0
total += sum || 0
end
h[@pivot_field.to_s.pluralize] = vals
h["sum_#{@data_field}"] = total
@table << OpenStruct.new(h)
end
end
def clean(s)
s.to_s.gsub(/[,.| -]/, '_').gsub(/__+/, '_')
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment