Sha256: 74f57edf74eb6ec60d2124d5131875f6eccfcc17a2b879cadef6be76d61a4ee7

Contents?: true

Size: 1.36 KB

Versions: 1

Compression:

Stored size: 1.36 KB

Contents

class SumSum < Hash
  def initialize(*args)
    @parent = args.pop if args[-1].is_a?(self.class)
    @name = args.shift
    @args = args.compact.dup
    @count = 0
    super()
  end
  
  attr_reader :name, :args, :count, :parent
  
  def add(hash, increase_by=1)
    key = hash[name]
    @count = @count + increase_by
    unless bottom?
      self[key] ||= SumSum.new(*args, self)
      self[key].add(hash, increase_by)
    end
    self
  end
  
  def share
    root? ? 1.0 : count/parent.count.to_f
  end
  
  def sort!
    values.each(&:sort!) unless bottom?
    to_a.tap do |array|
      array.reverse!(&:count)
      clear
      array.each{|k, v| self[k] = v }
    end
    self
  end
  
  def root?
    parent.nil?
  end
  
  def bottom?
    name.nil?
  end
  
  def inspect
    bottom? ? "#{count}" : "{#{name}:#{count} #{super.gsub(/^\{|\}$/, "")}}"
  end
  
  def dump
    return count if bottom?
    hash = {}
    each{ |k, v| hash[k] = v.dump }
    root? ? [all_args, hash] : hash
  end
  
  def self.load(data)
    new(*data[0]).tap do |sum_sum|
      sum_sum.add_from_dump(data[1])
    end
  end
  
  def add_from_dump(data, hash={}, level=0)
    data.each do |key, value|
      hash[all_args[level]] = key
      value.is_a?(Hash) ?
        add_from_dump(value, hash, level + 1) :
        add(hash, value)
    end
  end
  
  private
  
  def all_args
    [name] + args
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
sum_sum-0.0.3 lib/sum_sum.rb