require 'facets/conversion' class Hash # Converts all keys in the Hash accroding to the given block. # If the block return +nil+ for given key, then that key will be # left intact. # # foo = { :name=>'Gavin', :wife=>:Lisa } # foo.rekey{ |k| k.to_s } #=> { "name"=>"Gavin", "wife"=>:Lisa } # foo.inspect #=> { :name =>"Gavin", :wife=>:Lisa } # # CREDIT: Trans def rekey( meth=nil, &block ) raise ArgumentError, "2 for 1" if meth and block dup.send(:rekey!, meth, &block) end # Synonym for Hash#rekey, but modifies the receiver in place (and returns it). # # foo = { :name=>'Gavin', :wife=>:Lisa } # foo.rekey!{ |k| k.to_s } #=> { "name"=>"Gavin", "wife"=>:Lisa } # foo.inspect #=> { "name"=>"Gavin", "wife"=>:Lisa } # # CREDIT: Trans def rekey!( meth=nil, &block ) meth = :to_sym unless meth or block raise ArgumentError, "2 for 1" if meth and block block = meth.to_sym.to_proc if meth keys.each do |k| nk = block[k] self[nk]=delete(k) if nk end self end # Modifies the receiving Hash so that the value previously referred to by # _oldkey_ is also referenced by _newkey_; _oldkey_ is retained in the Hash. # If _oldkey_ does not exist as a key in the Hash, no change is effected. # # Returns a reference to the Hash. # # foo = { :name=>'Gavin', 'wife'=>:Lisa } # foo.alias!('name',:name) => { :name=>'Gavin', 'name'=>'Gavin', 'wife'=>:Lisa } # # foo = { :name=>'Gavin', 'wife'=>:Lisa } # foo.alias!('spouse','wife') => { :name=>'Gavin', 'wife'=>:Lisa, 'spouse'=>:Lisa } # # foo = { :name=>'Gavin', 'wife'=>:Lisa } # foo.alias!('bar','foo') => { :name=>'Gavin', 'wife'=>:Lisa } # # Note that if the _oldkey_ is reassigned, the reference will no longer exist, # and the _newkey_ will remain as it was. # # CREDIT: Gavin Sinclair def alias!( newkey, oldkey ) self[newkey] = self[oldkey] if self.has_key?(oldkey) self end # Swap the values of a pair of keys in place. # # {:a=>1,:b=>2}.swap!(:a,:b) #=> {:a=>2,:b=>1} # # CREDIT: Gavin Sinclair def swap!( key1, key2 ) tmp = self[key1] self[key1] = self[key2] self[key2] = tmp self end # Modifies the receiving Hash so that the value previously referred to by # _oldkey_ is referenced by _newkey_; _oldkey_ is removed from the Hash. # If _oldkey_ does not exist as a key in the Hash, no change is effected. # # Returns a reference to the Hash. # # foo = { :a=>1, :b=>2 } # foo.swapkey!('a',:a) #=> { 'a'=>1, :b=>2 } # foo.swapkey!('b',:b) #=> { 'a'=>1, 'b'=>2 } # foo.swapkey!('foo','bar') #=> { 'a'=>1, 'b'=>2 } # # CREDIT: Gavin Sinclair def swapkey!( newkey, oldkey ) self[newkey] = self.delete(oldkey) if self.has_key?(oldkey) self end end