Class: Array
- Inherits:
-
Object
- Object
- Array
- Defined in:
- lib/summaryse/core_ext/array.rb
Instance Method Summary collapse
-
#summaryse(agg) ⇒ Object
Apply a summarization to self.
Instance Method Details
#summaryse(agg) ⇒ Object
Apply a summarization to self
Base
Basic summarization operators are
* :avg, :count, :sum
* :mix, :max, :first, :last
* :union, :intersection
They suppose the existence of the corresponding dyadic operators like ‘+’ (i.e. sum, avg), ‘|’ (union), ‘&’ (intersection) on the array values.
Example:
[1, 4, 12, 7].summaryse(:sum) # => 24
Hashes
Summarizing arrays of hashes may be done by passing an hash of summarization expressions. Calls will be made recursively in this case:
Example:
[
{ :hobbies => [:ruby], :size => 12 },
{ :hobbies => [:music], :size => 17 }
].summaryse(:hobbies => :union, :size => :max)
# => {:hobbies => [:ruby, :music], :size => 17}
Use the nil key to specify the default aggregation to apply if not explcitely specified. A Proc object can also be passed as aggregation operator. In this case, it will be called with the array of values on which the aggregation must be done:
# In the example below, hobbies are summarized through default behavior
# provided by the nil key. Sizes are summarized by the lambda.
[
{ :hobbies => [:ruby], :size => 12 },
{ :hobbies => [:music], :size => 17 }
].summaryse(nil => :union, :size => lambda{|a| a.join(',')})
# => {:hobbies => [:ruby, :music], :size => "12,17"}
Arrays of Hashes
Summarizing arrays of arrays of hashes may be done by passing an array of two values. The first one is a ‘by key’, the second is the summarization hash to apply.
Example:
[
[ { :name => :yard, :for => [ :devel ] },
{ :name => :summaryse, :for => [ :runtime ] } ],
[ { :name => :summaryse, :for => [ :devel ] },
{ :name => :treetop, :for => [ :runtime ] } ]
].summaryse([ [:name], {:for => :union} ])
# => [ {:name => :yard, :for => [:devel] },
# {:name => :summaryse, :for => [:devel, :runtime] },
# {:name => :treetop, :for => [:runtime] } ]
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/summaryse/core_ext/array.rb', line 61 def summaryse(agg) case agg when Proc agg.call(self) when Symbol if fn = Summaryse.aggregator(agg) fn.call(self) elsif self.respond_to?(agg) self.send(agg) else raise ArgumentError, "No such aggregation function #{agg}" end when Hash big = Hash.new{|h,k| h[k] = []} agg.each_key{|k| big[k] = [] unless k.nil?} each{|t| t.each_pair{|k,v| big[k] << v}} Hash[big.collect{|k,v| if summ = (agg[k] || agg[nil]) res = v.summaryse(summ) res == Summaryse::BYPASS ? nil : [k, res] end }.compact] when Array by, agg = agg keys = [] grouped = Hash.new{|h,k| h[k] = []} flatten.each{|t| key = Hash[by.collect{|k| [k, t[k]] }] keys << key grouped[key] << t } agg = Hash[by.collect{|k| [k, :first]}].merge(agg) keys.uniq.collect{|key| grouped[key].summaryse(agg)} else if agg.respond_to?(:to_summaryse) summaryse(agg.to_summaryse) else raise ArgumentError, "Unable to convert #{agg} to an aggregation function" end end end |