Class: Hash
- Inherits:
-
Object
- Object
- Hash
- Defined in:
- lib/helpers/invert_hash.rb,
lib/helpers/hash_extensions.rb
Overview
Project Homepage: www.unixgods.org/~tilo/Ruby/invert_hash.html
This also appears in the “Facets of Ruby” library, and is mentioned in the O’Reilly Ruby Cookbook
Ruby’s Hash.invert method can’t handle the common case that two or more hash entries have the same value.
hash.invert.invert == h # => ? # is not generally true for Ruby's standard Hash#invert method
hash.inverse.inverse == h # => true # is true, even if the hash has duplicate values
If you have a Math background, you would expect that performing an “invert” operation twice would result in the original hash.
The Hash#inverse method provides this.
If you want to permanently overload Ruby’s original invert method, you may want to do this:
class Hash
alias old_invert invert # old Hash#invert is still accessible as Hash#old_invert
def invert
self.inverse # Hash#invert is not using inverse method
end
end
Instance Method Summary collapse
-
#inverse ⇒ Object
Returns a new hash, using given hash’s values as keys and using keys as values.
-
#invert ⇒ Object
monkey-patching Hash#invert method - it’s backwards compatible, but preserves duplicate values in the hash.
-
#old_invert ⇒ Object
original Hash#invert is still available as Hash#old_invert.
Instance Method Details
#inverse ⇒ Object
Returns a new hash, using given hash’s values as keys and using keys as values. If the input hash has duplicate values, the resulting hash will contain arrays as values. If you perform inverse twice, the output is identical to the original hash. e.g. no data is lost.
hash = { 'zero' => 0 , 'one' => 1, 'two' => 2, 'three' => 3 , # English numbers
'null' => 0, 'eins' => 1, 'zwei' => 2 , 'drei' => 3 } # German numbers
# Hash#inverse keeps track of duplicates, and preserves the input data
hash.inverse # => { 0=>["null", "zero"], 1=>["eins", "one"], 2=>["zwei", "two"], 3=>["drei", "three"] }
hash.inverse.inverse # => { "null"=>0, "zero"=>0, "eins"=>1, "one"=>1, "zwei"=>2, "two"=>2, "drei"=>3, "three"=>3 }
hash.inverse.inverse == hash # => true # works as you'd expect
# In Comparison:
#
# the standard Hash#invert loses data when dupclicate values are present
hash.invert # => { 0=>"null", 1=>"eins", 2=>"zwei", 3=>"drei" }
hash.invert.invert # => { "null"=>0, "eins"=>1, "zwei"=>2, "drei"=>3 } # data is lost
hash.invert.invert == hash # => false # oops, data was lost!
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/helpers/invert_hash.rb', line 83 def inverse i = Hash.new self.each_pair{ |k,v| if (v.class == Array) v.each{ |x| if i.has_key?(x) i[x] = [k,i[x]].flatten else i[x] = k end } else if i.has_key?(v) i[v] = [k,i[v]].flatten else i[v] = k end end } return i end |
#invert ⇒ Object
monkey-patching Hash#invert method - it’s backwards compatible, but preserves duplicate values in the hash
15 16 17 |
# File 'lib/helpers/hash_extensions.rb', line 15 def invert self.inverse end |
#old_invert ⇒ Object
original Hash#invert is still available as Hash#old_invert
12 |
# File 'lib/helpers/hash_extensions.rb', line 12 alias old_invert invert |