class Hash

Public Class Methods

sum(h1, h2) click to toggle source

def collapse_values_on_modulo(integer, min: nil, max: nil, shift: nil)

raise ArgumentError.new("Modulo integer had better be larger than shift") if integer <= shift.to_i

result = Hash.new(0)
hash = self.dup.populate_with_keys(min: min, max: max)
hash = hash.reject{|k, v| k < min.to_i}
hash = hash.reject{|k, v| k > max if max.present?}

hash.each do |k, v|
  if k%integer == shift.to_i
    result[k] = (k..(k + integer - 1)).map{|i| hash[i].to_i }.sum
  end
end

return result.fast_sort_keys

end

# File lib/creative_rails_utilities/hash.rb, line 39
def self.sum(h1, h2)
  # 1. take keys from both hashes
  keys = (h1.keys + h2.keys).uniq

  sum_hash = {}

  # 2. loop over the keys, summing numerics and recursing into hash-like structures
  keys.each do |key|
    v1 = h1[key]
    v2 = h2[key]

    sum_value = if v1.respond_to?(:keys) && v2.respond_to?(:keys)
      # O-1 recuring needed only if both are hash-like
      sum(v1, v2)
    elsif v1.present? && v2.blank?
      # O-3a sum possibe because either is nil (one of the hashes does not have the key at all)
      v1
    elsif v1.blank? && v2.present?
      # O-3b sum possibe because either is nil (one of the hashes does not have the key at all)
      v2
    elsif v1.respond_to?(:to_f) && v2.respond_to?(:to_f)
      # O-2 sum possible because both numerics
      v1 + v2
    elsif v1.present? && v2.present? && (v1.respond_to?(:to_f) != v2.respond_to?(:to_f))
      # 0-4 error because types mismatch
      raise ArgumentError.new("Sorry, can not sum these hashes, there's value collision in '#{key}' keys")
    end

    sum_hash[key] = sum_value
  end

  return sum_hash
end

Public Instance Methods

fast_sort_keys() click to toggle source
# File lib/creative_rails_utilities/hash.rb, line 3
def fast_sort_keys
  keys = self.keys.sort
  Hash[keys.zip(self.values_at(*keys))]
end
populate_with_keys(min: nil, max: nil, explicit_default_value: 0) click to toggle source

TODO write fast sort values

# File lib/creative_rails_utilities/hash.rb, line 10
def populate_with_keys(min: nil, max: nil, explicit_default_value: 0)
  start_key = min || self.keys.min
  end_key = max || self.keys.max

  result = self.dup
  (start_key..end_key).each do |k|
    result[k] = self[k] || explicit_default_value
  end

  return result
end