Module: Aquarium::Extensions::HashHelper
- Included in:
- Hash
- Defined in:
- lib/aquarium/extensions/hash.rb
Instance Method Summary collapse
- #and(other_hash) ⇒ Object (also: #intersection, #&)
-
#eql_when_keys_compared?(other) ⇒ Boolean
It appears that Hash#== uses Object#== (i.e., self.object_id == other.object_id) when comparing hash keys.
- #equivalent_key(key) ⇒ Object
- #minus(other_hash) ⇒ Object (also: #-)
-
#or(other_hash) ⇒ Object
(also: #union, #|)
Union of self with a second hash, which returns a new hash.
Instance Method Details
#and(other_hash) ⇒ Object Also known as: intersection, &
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# 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 |
#eql_when_keys_compared?(other) ⇒ Boolean
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.)
89 90 91 92 93 94 95 96 97 98 99 100 |
# 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) ⇒ Object
102 103 104 105 |
# File 'lib/aquarium/extensions/hash.rb', line 102 def equivalent_key key i = keys.index(key) i.nil? ? nil : keys[i] end |
#minus(other_hash) ⇒ Object Also known as: -
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# 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 |
#or(other_hash) ⇒ Object Also known as: union, |
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.
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# 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 |