module Aquarium::Extensions::HashHelper

Public Instance Methods

&(other_hash) click to toggle source
Alias for: and
-(other_hash) click to toggle source
Alias for: minus
and(other_hash) { |value1, value2| ... } click to toggle source
# File lib/aquarium/extensions/hash.rb, line 7
def and other_hash
  return {} if other_hash.nil? or other_hash.empty?
  keys2 = Set.new(self.keys).intersection(Set.new(other_hash.keys))
  result = {}
  keys2.each do |key|
    value1 = self[key]
    value2 = other_hash[key]
    if block_given?
      result[key] = yield value1, value2
    elsif value1 == value2 or value1.eql?(value2)
      result[key] = value1
    elsif value1.class == value2.class && value1.respond_to?(:&)
      result[key] = (value1 & value2)
    end
  end
  result
end
Also aliased as: intersection, &
eql_when_keys_compared?(other) click to toggle source

It appears that Hash#== uses Object#== (i.e., self.object_id == other.object_id) when comparing hash keys. (Array#== uses the overridden #== for the elements.)

# File lib/aquarium/extensions/hash.rb, line 89
def eql_when_keys_compared? other
  return true  if     self.object_id == other.object_id
  return false unless self.class     == other.class
  keys1 = sort_keys(self.keys)
  keys2 = sort_keys(other.keys)
  return false unless keys1.eql?(keys2)
  (0...keys1.size).each do |index|
    # Handle odd cases where eql? and == behavior differently
    return false unless self[keys1[index]].eql?(other[keys2[index]]) || self[keys1[index]] == other[keys2[index]]
  end
  true
end
equivalent_key(key) click to toggle source
# File lib/aquarium/extensions/hash.rb, line 102
def equivalent_key key
  i = keys.index(key)
  i.nil? ? nil : keys[i] 
end
intersection(other_hash) click to toggle source
Alias for: and
minus(other_hash) { |value1, value2| ... } click to toggle source
# File lib/aquarium/extensions/hash.rb, line 59
def minus other_hash
  result = self.dup
  return result if other_hash.nil? or other_hash.empty?
  result.each do |key, value| 
    if other_hash.include?(key)
      value1 = self[key]
      value2 = other_hash[key]
      if block_given?
        result[key] = yield value1, value2
      elsif value2.nil?
        # do nothing
      elsif value1 == value2 or value1.eql?(value2)
        result.delete key
      elsif value1.class == value2.class && value1.respond_to?(:-)
        result[key] = (value1 - value2)
      else  # Hash#merge behavior
        result.delete key
      end
    elsif block_given?
      # Since the block might change the value's type (e.g., [] => Set...)
      result[key] = yield result[key], nil
    end
  end
  result
end
Also aliased as: -
or(other_hash) { |value1, value2| ... } click to toggle source

Union of self with a second hash, which returns a new hash. It’s different from Hash#merge in that it attempts to merge non-equivalent values for the same key, using a block, if given, or if they are of the same type and respond to #|, using #| to merge the two values. Otherwise, it behaves like Hash#merge.

# File lib/aquarium/extensions/hash.rb, line 32
def or other_hash
  return self if other_hash.nil?
  result = {}
  new_keys = self.keys | other_hash.keys
  new_keys.each do |key|
    value1 = self[key]
    value2 = other_hash[key]
    if block_given?
      result[key] = yield value1, value2
    elsif value1.nil? and not value2.nil?
      result[key] = value2
    elsif (not value1.nil?) and value2.nil?
      result[key] = value1
    elsif value1 == value2 or value1.eql?(value2)
      result[key] = value1 
    elsif value1.class == value2.class && value1.respond_to?(:|)
      result[key] = (value1 | value2)
    else  # Hash#merge behavior
      result[key] = value2
    end
  end
  result
end
Also aliased as: union, |
union(other_hash) click to toggle source
Alias for: or
|(other_hash) click to toggle source
Alias for: or