- &
- &
- *
- *
- +
- +
- -
- -
- <<
- <<
- alias!
- alias!
- argumentize
- argumentize
- autonew
- autonew
- collate
- collate
- collate!
- collate!
- delete_unless
- delete_unless
- delete_values
- delete_values
- delete_values_at
- delete_values_at
- diff
- diff
- each_with_key
- each_with_key
- except
- except
- except!
- except!
- graph!
- graph!
- has_keys?
- has_keys?
- has_only_keys?
- has_only_keys?
- insert
- insert
- inverse
- inverse
- join
- join
- keys?
- keys?
- mash!
- mash!
- only_keys?
- only_keys?
- recursive_merge
- recursive_merge
- recursive_merge!
- recursive_merge!
- recursively
- recursively
- recursively!
- recursively!
- rekey
- rekey
- rekey!
- rekey!
- replace_each
- replace_each
- reverse_merge
- reverse_merge
- reverse_merge!
- reverse_merge!
- reverse_update
- reverse_update
- select!
- select!
- slice
- slice
- slice!
- slice!
- swap!
- swap!
- to_h
- to_proc
- to_proc
- to_proc_with_reponse
- to_proc_with_reponse
- to_struct
- to_struct
- traverse
- traverse
- traverse!
- traverse!
- update_each
- update_each
- update_keys
- update_keys
- update_values
- update_values
- weave
- weave
- zipnew
- zipnew
- |
- |
Hash which auto initializes it‘s children.
ah = Hash.autonew ah['section one']['param one'] = 4 ah['section one']['param two'] = 5 ah['section one']['param three'] = 2 ah['section one']['param four'] = 3 p ah # {"section one"=>{"param one"=>4, "param four"=>3, "param three"=>2, "param two"=>5}} p ah['section one'].keys # ["param one", "param four", "param three", "param two"]
CREDIT: Trans CREDIT: Jan Molic
[ show source ]
# File lib/core/facets/hash/autonew.rb, line 20 def self.autonew(*args) #new(*args){|a,k| a[k] = self.class::new(*args)} leet = lambda { |hsh, key| hsh[key] = new( &leet ) } new(*args,&leet) end
Hash which auto initializes it‘s children.
ah = Hash.autonew ah['section one']['param one'] = 4 ah['section one']['param two'] = 5 ah['section one']['param three'] = 2 ah['section one']['param four'] = 3 p ah # {"section one"=>{"param one"=>4, "param four"=>3, "param three"=>2, "param two"=>5}} p ah['section one'].keys # ["param one", "param four", "param three", "param two"]
CREDIT: Trans CREDIT: Jan Molic
[ show source ]
# File lib/core/facets/hash/autonew.rb, line 20 def self.autonew(*args) #new(*args){|a,k| a[k] = self.class::new(*args)} leet = lambda { |hsh, key| hsh[key] = new( &leet ) } new(*args,&leet) end
Creates a new hash from two arrays —a keys array and a values array.
Hash.zipnew(["a","b","c"], [1,2,3]) #=> { "a"=>1, "b"=>2, "c"=>3 } CREDIT: Trans CREDIT: Ara T. Howard
[ show source ]
# File lib/core/facets/hash/autonew.rb, line 35 def self.zipnew(keys,values) # or some better name h = {} keys.size.times{ |i| h[ keys[i] ] = values[i] } h end
Creates a new hash from two arrays —a keys array and a values array.
Hash.zipnew(["a","b","c"], [1,2,3]) #=> { "a"=>1, "b"=>2, "c"=>3 } CREDIT: Trans CREDIT: Ara T. Howard
[ show source ]
# File lib/core/facets/hash/autonew.rb, line 35 def self.zipnew(keys,values) # or some better name h = {} keys.size.times{ |i| h[ keys[i] ] = values[i] } h end
Hash intersection. Two hashes intersect when their pairs are equal.
{:a=>1,:b=>2} & {:a=>1,:c=>3} #=> {:a=>1}
A hash can also be intersected with an array to intersect keys only.
{:a=>1,:b=>2} & [:a,:c] #=> {:a=>1}
The later form is similar to pairs_at. The differ only in that pairs_at will return a nil value for a key not in the hash, but #& will not.
CREDIT: Trans
[ show source ]
# File lib/core/facets/hash/op.rb, line 19 def &(other) case other when Array k = (keys & other) Hash[*(k.zip(values_at(*k)).flatten)] else x = (to_a & other.to_a).inject([]) do |a, kv| a.concat kv; a end Hash[*x] end end
Hash intersection. Two hashes intersect when their pairs are equal.
{:a=>1,:b=>2} & {:a=>1,:c=>3} #=> {:a=>1}
A hash can also be intersected with an array to intersect keys only.
{:a=>1,:b=>2} & [:a,:c] #=> {:a=>1}
The later form is similar to pairs_at. The differ only in that pairs_at will return a nil value for a key not in the hash, but #& will not.
CREDIT: Trans
[ show source ]
# File lib/core/facets/hash/op.rb, line 19 def &(other) case other when Array k = (keys & other) Hash[*(k.zip(values_at(*k)).flatten)] else x = (to_a & other.to_a).inject([]) do |a, kv| a.concat kv; a end Hash[*x] end end
Like merge operator ’+’ but merges in reverse order.
h1 = { :a=>1 } h2 = { :a=>2, :b=>3 } h1 + h2 #=> { :a=>2, :b=>3 } h1 * h2 #=> { :a=>1, :b=>3 } CREDIT: Trans
[ show source ]
# File lib/core/facets/hash/op.rb, line 80 def *(other) other.merge(self) end
Like merge operator ’+’ but merges in reverse order.
h1 = { :a=>1 } h2 = { :a=>2, :b=>3 } h1 + h2 #=> { :a=>2, :b=>3 } h1 * h2 #=> { :a=>1, :b=>3 } CREDIT: Trans
[ show source ]
# File lib/core/facets/hash/op.rb, line 80 def *(other) other.merge(self) end
Operator for merge.
CREDIT: Trans
[ show source ]
# File lib/core/facets/hash/op.rb, line 44 def +(other) merge(other) end
Operator for merge.
CREDIT: Trans
[ show source ]
# File lib/core/facets/hash/op.rb, line 44 def +(other) merge(other) end
Operator for remove hash paris. If another hash is given the pairs are only removed if both key and value are equal. If an array is given then matching keys are removed.
CREDIT: Trans
[ show source ]
# File lib/core/facets/hash/op.rb, line 54 def -(other) h = self.dup if other.respond_to?(:to_ary) other.to_ary.each do |k| h.delete(k) end else other.each do |k,v| if h.key?(k) h.delete(k) if v == h[k] end end end h end
Operator for remove hash paris. If another hash is given the pairs are only removed if both key and value are equal. If an array is given then matching keys are removed.
CREDIT: Trans
[ show source ]
# File lib/core/facets/hash/op.rb, line 54 def -(other) h = self.dup if other.respond_to?(:to_ary) other.to_ary.each do |k| h.delete(k) end else other.each do |k,v| if h.key?(k) h.delete(k) if v == h[k] end end end h end
Can be used like update, or passed as two-element [key,value] array.
CREDIT: Trans
[ show source ]
# File lib/core/facets/hash/update.rb, line 8 def <<(other) if other.respond_to?(:to_ary) self.store(*other) else update(other) end end
Can be used like update, or passed as two-element [key,value] array.
CREDIT: Trans
[ show source ]
# File lib/core/facets/hash/update.rb, line 8 def <<(other) if other.respond_to?(:to_ary) self.store(*other) else update(other) end 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
TODO: Rename to aliaskey or something else.
[ show source ]
# File lib/core/facets/hash/alias.rb, line 25 def alias!(newkey, oldkey) self[newkey] = self[oldkey] if self.has_key?(oldkey) 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
TODO: Rename to aliaskey or something else.
[ show source ]
# File lib/core/facets/hash/alias.rb, line 25 def alias!(newkey, oldkey) self[newkey] = self[oldkey] if self.has_key?(oldkey) self end
Turn a hash into arguments.
h = { :list => [1,2], :base => "HI" } h.argumentize #=> [ [], { :list => [1,2], :base => "HI" } ] h.argumentize(:list) #=> [ [1,2], { :base => "HI" } ] h.argumentize(:base) #=> [ ["HI"], { :list => [1,2] } ]
[ show source ]
# File lib/core/facets/hash/argumentize.rb, line 10 def argumentize(args_field=nil) config = dup if args_field args = [config.delete(args_field)].flatten.compact else args = [] end args << config return args end
Turn a hash into arguments.
h = { :list => [1,2], :base => "HI" } h.argumentize #=> [ [], { :list => [1,2], :base => "HI" } ] h.argumentize(:list) #=> [ [1,2], { :base => "HI" } ] h.argumentize(:base) #=> [ ["HI"], { :list => [1,2] } ]
[ show source ]
# File lib/core/facets/hash/argumentize.rb, line 10 def argumentize(args_field=nil) config = dup if args_field args = [config.delete(args_field)].flatten.compact else args = [] end args << config return args end
Merge the values of this hash with those from another, setting all values to be arrays representing the values from both hashes.
{ :a=>1, :b=>2 }.collate :a=>3, :b=>4, :c=>5 #=> { :a=>[1,3], :b=>[2,4], :c=>[5] } CREDIT: Gavin Kistner (Phrogz)
[ show source ]
# File lib/core/facets/hash/collate.rb, line 11 def collate(other_hash) dup.collate!(other_hash) end
Merge the values of this hash with those from another, setting all values to be arrays representing the values from both hashes.
{ :a=>1, :b=>2 }.collate :a=>3, :b=>4, :c=>5 #=> { :a=>[1,3], :b=>[2,4], :c=>[5] } CREDIT: Gavin Kistner (Phrogz)
[ show source ]
# File lib/core/facets/hash/collate.rb, line 11 def collate(other_hash) dup.collate!(other_hash) end
The same as collate, but modifies the receiver in place.
[ show source ]
# File lib/core/facets/hash/collate.rb, line 17 def collate!(other_hash) # Prepare, ensuring every existing key is already an Array each do |key, value| if value.is_a?(Array) self[key] = value else self[key] = [value] end end # Collate with values from other_hash other_hash.each do |key, value| if self[key] if value.is_a?(Array) self[key].concat( value ) else self[key] << value end elsif value.is_a?(Array) self[key] = value else self[key] = [value] end end #each{ |key, value| value.uniq! } if options[ :uniq ] self end
The same as collate, but modifies the receiver in place.
[ show source ]
# File lib/core/facets/hash/collate.rb, line 17 def collate!(other_hash) # Prepare, ensuring every existing key is already an Array each do |key, value| if value.is_a?(Array) self[key] = value else self[key] = [value] end end # Collate with values from other_hash other_hash.each do |key, value| if self[key] if value.is_a?(Array) self[key].concat( value ) else self[key] << value end elsif value.is_a?(Array) self[key] = value else self[key] = [value] end end #each{ |key, value| value.uniq! } if options[ :uniq ] self end
Inverse of delete_if.
CREDIT: Daniel Schierbeck
[ show source ]
# File lib/core/facets/hash/delete.rb, line 11 def delete_unless #:yield: delete_if{ |key, value| ! yield(key, value) } end
Inverse of delete_if.
CREDIT: Daniel Schierbeck
[ show source ]
# File lib/core/facets/hash/delete.rb, line 11 def delete_unless #:yield: delete_if{ |key, value| ! yield(key, value) } end
Minor modification to Ruby‘s Hash#delete method allowing it to take multiple keys.
hsh = { :a => 1, :b => 2 } hsh.delete_values(1) hsh #=> { :b => 2 } CREDIT: Daniel Schierbeck
[ show source ]
# File lib/core/facets/hash/delete.rb, line 24 def delete_values(*values) keys.map{ |key| delete(key) if values.include?(fetch(key)) } end
Minor modification to Ruby‘s Hash#delete method allowing it to take multiple keys.
hsh = { :a => 1, :b => 2 } hsh.delete_values(1) hsh #=> { :b => 2 } CREDIT: Daniel Schierbeck
[ show source ]
# File lib/core/facets/hash/delete.rb, line 24 def delete_values(*values) keys.map{ |key| delete(key) if values.include?(fetch(key)) } end
Minor modification to Ruby‘s Hash#delete method allowing it to take multiple keys.
This works niely with hash#[] and Hash#[]= facets.
hsh[:a, :b, :c] = 1, 2, 3 a, b, c = hsh.delete_values_at(:a, :b, :c) [a, b, c] #=> [1, 2, 3] hsh #=> {} CREDIT: Daniel Schierbeck
[ show source ]
# File lib/core/facets/hash/delete.rb, line 42 def delete_values_at(*keys, &yld) keys.map{|key| delete(key, &yld) } end
Minor modification to Ruby‘s Hash#delete method allowing it to take multiple keys.
This works niely with hash#[] and Hash#[]= facets.
hsh[:a, :b, :c] = 1, 2, 3 a, b, c = hsh.delete_values_at(:a, :b, :c) [a, b, c] #=> [1, 2, 3] hsh #=> {} CREDIT: Daniel Schierbeck
[ show source ]
# File lib/core/facets/hash/delete.rb, line 42 def delete_values_at(*keys, &yld) keys.map{|key| delete(key, &yld) } end
Difference comparison of two hashes.
[ show source ]
# File lib/core/facets/hash/diff.rb, line 5 def diff(hash) h1 = self.dup.delete_if{ |k,v| hash[k] == v } h2 = hash.dup.delete_if{ |k,v| has_key?(k) } h1.merge(h2) end
Difference comparison of two hashes.
[ show source ]
# File lib/core/facets/hash/diff.rb, line 5 def diff(hash) h1 = self.dup.delete_if{ |k,v| hash[k] == v } h2 = hash.dup.delete_if{ |k,v| has_key?(k) } h1.merge(h2) end
Each with key is like each_pair but reverses the order the parameters to [value,key] instead of [key,value].
CREDIT: Trans
[ show source ]
# File lib/core/facets/hash/keys.rb, line 40 def each_with_key( &yld ) each_pair{ |k,v| yld.call(v,k) } end
Each with key is like each_pair but reverses the order the parameters to [value,key] instead of [key,value].
CREDIT: Trans
[ show source ]
# File lib/core/facets/hash/keys.rb, line 40 def each_with_key( &yld ) each_pair{ |k,v| yld.call(v,k) } end
Returns a new hash less the given keys.
[ show source ]
# File lib/core/facets/hash/except.rb, line 5 def except(*less_keys) slice(*keys - less_keys) end
Returns a new hash less the given keys.
[ show source ]
# File lib/core/facets/hash/except.rb, line 5 def except(*less_keys) slice(*keys - less_keys) end
Replaces hash with new hash less the given keys. This returns the hash of keys removed.
h = {:a=>1, :b=>2, :c=>3} h.except!(:a) #=> {:a=>1} h #=> {:b=>2,:c=>3}
[ show source ]
# File lib/core/facets/hash/except.rb, line 16 def except!(*less_keys) removed = slice(*less_keys) replace(except(*less_keys)) removed end
Replaces hash with new hash less the given keys. This returns the hash of keys removed.
h = {:a=>1, :b=>2, :c=>3} h.except!(:a) #=> {:a=>1} h #=> {:b=>2,:c=>3}
[ show source ]
# File lib/core/facets/hash/except.rb, line 16 def except!(*less_keys) removed = slice(*less_keys) replace(except(*less_keys)) removed end
Returns true or false whether the hash contains the given keys.
h = { :a => 1, :b => 2 } h.has_keys?( :a ) #=> true h.has_keys?( :c ) #=> false CREDIT: Trans
[ show source ]
# File lib/core/facets/hash/keys.rb, line 12 def has_keys?(*check_keys) unknown_keys = check_keys - self.keys return unknown_keys.empty? end
Returns true or false whether the hash contains the given keys.
h = { :a => 1, :b => 2 } h.has_keys?( :a ) #=> true h.has_keys?( :c ) #=> false CREDIT: Trans
[ show source ]
# File lib/core/facets/hash/keys.rb, line 12 def has_keys?(*check_keys) unknown_keys = check_keys - self.keys return unknown_keys.empty? end
Returns true if the hash contains only the given keys, otherwise false.
h = { :a => 1, :b => 2 } h.has_only_keys?( :a, :b ) #=> true h.has_only_keys?( :a ) #=> false CREDIT: Trans
[ show source ]
# File lib/core/facets/hash/keys.rb, line 28 def has_only_keys?(*check_keys) unknown_keys = self.keys - check_keys return unknown_keys.empty? end
Returns true if the hash contains only the given keys, otherwise false.
h = { :a => 1, :b => 2 } h.has_only_keys?( :a, :b ) #=> true h.has_only_keys?( :a ) #=> false CREDIT: Trans
[ show source ]
# File lib/core/facets/hash/keys.rb, line 28 def has_only_keys?(*check_keys) unknown_keys = self.keys - check_keys return unknown_keys.empty? end
As with store but only if the key isn‘t already in the hash.
TODO: Would store? be a better name?
CREDIT: Trans
[ show source ]
# File lib/core/facets/hash/insert.rb, line 10 def insert(name, value) if key?(name) false else store(name,value) true end end
As with store but only if the key isn‘t already in the hash.
TODO: Would store? be a better name?
CREDIT: Trans
[ show source ]
# File lib/core/facets/hash/insert.rb, line 10 def insert(name, value) if key?(name) false else store(name,value) true end end
Create a "true" inverse hash by storing mutliple values in Arrays.
h = {"a"=>3, "b"=>3, "c"=>3, "d"=>2, "e"=>9, "f"=>3, "g"=>9} h.invert #=> {2=>"d", 3=>"f", 9=>"g"} h.inverse #=> {2=>"d", 3=>["f", "c", "b", "a"], 9=>["g", "e"]} h.inverse.inverse #=> {"a"=>3, "b"=>3, "c"=>3, "d"=>2, "e"=>9, "f"=>3, "g"=>9} h.inverse.inverse == h #=> true CREDIT: Tilo Sloboda
[ show source ]
# File lib/core/facets/hash/inverse.rb, line 14 def inverse i = Hash.new self.each_pair{ |k,v| if (Array === v) v.each{ |x| i[x] = ( i.has_key?(x) ? [k,i[x]].flatten : k ) } else i[v] = ( i.has_key?(v) ? [k,i[v]].flatten : k ) end } return i end
Create a "true" inverse hash by storing mutliple values in Arrays.
h = {"a"=>3, "b"=>3, "c"=>3, "d"=>2, "e"=>9, "f"=>3, "g"=>9} h.invert #=> {2=>"d", 3=>"f", 9=>"g"} h.inverse #=> {2=>"d", 3=>["f", "c", "b", "a"], 9=>["g", "e"]} h.inverse.inverse #=> {"a"=>3, "b"=>3, "c"=>3, "d"=>2, "e"=>9, "f"=>3, "g"=>9} h.inverse.inverse == h #=> true CREDIT: Tilo Sloboda
[ show source ]
# File lib/core/facets/hash/inverse.rb, line 14 def inverse i = Hash.new self.each_pair{ |k,v| if (Array === v) v.each{ |x| i[x] = ( i.has_key?(x) ? [k,i[x]].flatten : k ) } else i[v] = ( i.has_key?(v) ? [k,i[v]].flatten : k ) end } return i end
Like Array#join but specialized to Hash.
CREDIT: Mauricio Fernandez
[ show source ]
# File lib/core/facets/hash/join.rb, line 7 def join(pair_divider='', elem_divider='') s = [] each_pair { |k,v| s << "#{k}#{pair_divider}#{v}" } s.join(elem_divider) end
Like Array#join but specialized to Hash.
CREDIT: Mauricio Fernandez
[ show source ]
# File lib/core/facets/hash/join.rb, line 7 def join(pair_divider='', elem_divider='') s = [] each_pair { |k,v| s << "#{k}#{pair_divider}#{v}" } s.join(elem_divider) end
In place version of mash.
NOTE: Hash#mash! is only useful for Hash. It is not generally applicable to Enumerable.
[ show source ]
# File lib/core/facets/hash/mash.rb, line 10 def mash!(&yld) replace(mash(&yld)) end
In place version of mash.
NOTE: Hash#mash! is only useful for Hash. It is not generally applicable to Enumerable.
[ show source ]
# File lib/core/facets/hash/mash.rb, line 10 def mash!(&yld) replace(mash(&yld)) end
Same as Hash#merge but recursively merges sub-hashes.
[ show source ]
# File lib/core/facets/hash/recursive_merge.rb, line 5 def recursive_merge(other) hash = self.dup other.each do |key, value| myval = self[key] if value.is_a?(Hash) && myval.is_a?(Hash) hash[key] = myval.recursive_merge(value) else hash[key] = value end end hash end
Same as Hash#merge but recursively merges sub-hashes.
[ show source ]
# File lib/core/facets/hash/recursive_merge.rb, line 5 def recursive_merge(other) hash = self.dup other.each do |key, value| myval = self[key] if value.is_a?(Hash) && myval.is_a?(Hash) hash[key] = myval.recursive_merge(value) else hash[key] = value end end hash end
Same as Hash#merge! but recursively merges sub-hashes.
[ show source ]
# File lib/core/facets/hash/recursive_merge.rb, line 20 def recursive_merge!(other) other.each do |key, value| myval = self[key] if value.is_a?(Hash) && myval.is_a?(Hash) myval.recursive_merge!(value) else self[key] = value end end self end
Same as Hash#merge! but recursively merges sub-hashes.
[ show source ]
# File lib/core/facets/hash/recursive_merge.rb, line 20 def recursive_merge!(other) other.each do |key, value| myval = self[key] if value.is_a?(Hash) && myval.is_a?(Hash) myval.recursive_merge!(value) else self[key] = value end end self end
Apply a block to hash, and recursively apply that block to each subhash.
h = {:a=>1, :b=>{:b1=>1, :b2=>2}} h.recursively{|h| h.rekey(&:to_s) } => {"a"=>1, "b"=>{"b1"=>1, "b2"=>2}}
[ show source ]
# File lib/core/facets/hash/recursively.rb, line 10 def recursively(&block) h = inject({}) do |hash, (key, value)| if value.is_a?(Hash) hash[key] = value.recursively(&block) else hash[key] = value end hash end yield h end
Apply a block to hash, and recursively apply that block to each subhash.
h = {:a=>1, :b=>{:b1=>1, :b2=>2}} h.recursively{|h| h.rekey(&:to_s) } => {"a"=>1, "b"=>{"b1"=>1, "b2"=>2}}
[ show source ]
# File lib/core/facets/hash/recursively.rb, line 10 def recursively(&block) h = inject({}) do |hash, (key, value)| if value.is_a?(Hash) hash[key] = value.recursively(&block) else hash[key] = value end hash end yield h end
[ show source ]
# File lib/core/facets/hash/recursively.rb, line 24 def recursively!(&block) replace(recursively(&block)) end
[ show source ]
# File lib/core/facets/hash/recursively.rb, line 24 def recursively!(&block) replace(recursively(&block)) end
rekey(to_key, from_key) rekey{ |key| … }
If two keys are given, then the second key is changed to the first.
foo = { :a=>1, :b=>2 } foo.rekey('a',:a) #=> { 'a'=>1, :b=>2 } foo.rekey('b',:b) #=> { 'a'=>1, 'b'=>2 } foo.rekey('foo','bar') #=> { 'a'=>1, 'b'=>2 }
If a block is given, converts all keys in the Hash accroding to the given block. If the block returns 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 CREDIT: Gavin Kistner
[ show source ]
# File lib/core/facets/hash/rekey.rb, line 27 def rekey(*args, &block) dup.rekey!(*args, &block) end
rekey(to_key, from_key) rekey{ |key| … }
If two keys are given, then the second key is changed to the first.
foo = { :a=>1, :b=>2 } foo.rekey('a',:a) #=> { 'a'=>1, :b=>2 } foo.rekey('b',:b) #=> { 'a'=>1, 'b'=>2 } foo.rekey('foo','bar') #=> { 'a'=>1, 'b'=>2 }
If a block is given, converts all keys in the Hash accroding to the given block. If the block returns 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 CREDIT: Gavin Kistner
[ show source ]
# File lib/core/facets/hash/rekey.rb, line 27 def rekey(*args, &block) dup.rekey!(*args, &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 CREDIT: Gavin Kistner
[ show source ]
# File lib/core/facets/hash/rekey.rb, line 40 def rekey!(*args, &block) # for backward comptability (TODO: DEPRECATE). block = args.pop.to_sym.to_proc if args.size == 1 # if no args use block. if args.empty? block = lambda{|k| k.to_sym} unless block keys.each do |k| nk = block[k] self[nk]=delete(k) if nk end else raise ArgumentError, "3 for 2" if block to, from = *args self[to] = self.delete(from) if self.has_key?(from) end self 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 CREDIT: Gavin Kistner
[ show source ]
# File lib/core/facets/hash/rekey.rb, line 40 def rekey!(*args, &block) # for backward comptability (TODO: DEPRECATE). block = args.pop.to_sym.to_proc if args.size == 1 # if no args use block. if args.empty? block = lambda{|k| k.to_sym} unless block keys.each do |k| nk = block[k] self[nk]=delete(k) if nk end else raise ArgumentError, "3 for 2" if block to, from = *args self[to] = self.delete(from) if self.has_key?(from) end self end
Same as update_each, but deletes the key element first.
CREDIT: Trans
[ show source ]
# File lib/core/facets/hash/update.rb, line 66 def replace_each # :yield: dup.each do |k,v| delete(k) update(yield(k,v)) end self end
Same as update_each, but deletes the key element first.
CREDIT: Trans
[ show source ]
# File lib/core/facets/hash/update.rb, line 66 def replace_each # :yield: dup.each do |k,v| delete(k) update(yield(k,v)) end self end
Allows for reverse merging where its the keys in the calling hash that wins over those in the other_hash. This is particularly useful for initializing an incoming option hash with default values:
def setup(options = {}) options.reverse_merge! :size => 25, :velocity => 10 end
The default :size and :velocity is only set if the options passed in doesn‘t already have those keys set.
[ show source ]
# File lib/core/facets/hash/merge.rb, line 15 def reverse_merge(other) other.merge(self) end
Allows for reverse merging where its the keys in the calling hash that wins over those in the other_hash. This is particularly useful for initializing an incoming option hash with default values:
def setup(options = {}) options.reverse_merge! :size => 25, :velocity => 10 end
The default :size and :velocity is only set if the options passed in doesn‘t already have those keys set.
[ show source ]
# File lib/core/facets/hash/merge.rb, line 15 def reverse_merge(other) other.merge(self) end
Inplace form of reverse_merge.
[ show source ]
# File lib/core/facets/hash/merge.rb, line 21 def reverse_merge!(other) replace(reverse_merge(other)) end
Inplace form of reverse_merge.
[ show source ]
# File lib/core/facets/hash/merge.rb, line 21 def reverse_merge!(other) replace(reverse_merge(other)) end
Alias for reverse_merge!
Alias for reverse_merge!
In-place version of Hash#select. The opposite of the built-in Hash#reject!.
CREDIT Gavin Sinclair CREDIT Noah Gibbs
[ show source ]
# File lib/core/facets/hash/select.rb, line 9 def select! reject! { |k,v| not yield(k,v) } end
In-place version of Hash#select. The opposite of the built-in Hash#reject!.
CREDIT Gavin Sinclair CREDIT Noah Gibbs
[ show source ]
# File lib/core/facets/hash/select.rb, line 9 def select! reject! { |k,v| not yield(k,v) } end
Returns a new hash with only the given keys.
[ show source ]
# File lib/core/facets/hash/slice.rb, line 7 def slice(*keep_keys) h = {} keep_keys.each do |key| h[key] = fetch(key) end h end
Returns a new hash with only the given keys.
[ show source ]
# File lib/core/facets/hash/slice.rb, line 7 def slice(*keep_keys) h = {} keep_keys.each do |key| h[key] = fetch(key) end h end
Replaces hash with a new hash having only the given keys. This return the hash of keys removed.
[ show source ]
# File lib/core/facets/hash/slice.rb, line 18 def slice!(*keep_keys) removed = except(*keep_keys) replace(slice(*keep_keys)) removed end
Replaces hash with a new hash having only the given keys. This return the hash of keys removed.
[ show source ]
# File lib/core/facets/hash/slice.rb, line 18 def slice!(*keep_keys) removed = except(*keep_keys) replace(slice(*keep_keys)) removed 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
[ show source ]
# File lib/core/facets/hash/swap.rb, line 9 def swap!(key1, key2) tmp = self[key1] self[key1] = self[key2] self[key2] = tmp 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
[ show source ]
# File lib/core/facets/hash/swap.rb, line 9 def swap!(key1, key2) tmp = self[key1] self[key1] = self[key2] self[key2] = tmp self end
Return a rehashing of self.
{"a"=>1,"b"=>2}.to_h #=> {"b"=>2,"a"=>1}
CREDIT: Forian Gross
[ show source ]
# File lib/core/facets/to_hash.rb, line 54 def to_h; rehash; end
Constructs a Proc object from a hash such that the parameter of the Proc is assigned the hash keys as attributes.
h = { :a => 1 } p = h.to_proc o = OpenStruct.new p.call(o) o.a #=> 1
CREDIT: Trans
[ show source ]
# File lib/core/facets/hash/to_proc.rb, line 15 def to_proc lambda do |o| self.each do |k,v| ke = "#{k}=" o.__send__(ke, v) end end end
Constructs a Proc object from a hash such that the parameter of the Proc is assigned the hash keys as attributes.
h = { :a => 1 } p = h.to_proc o = OpenStruct.new p.call(o) o.a #=> 1
CREDIT: Trans
[ show source ]
# File lib/core/facets/hash/to_proc.rb, line 15 def to_proc lambda do |o| self.each do |k,v| ke = "#{k}=" o.__send__(ke, v) end end end
A fault-tolerent version of to_proc.
It works just like to_proc, but the block will make sure# the object responds to the assignment.
CREDIT: Trans
[ show source ]
# File lib/core/facets/hash/to_proc.rb, line 31 def to_proc_with_reponse lambda do |o| self.each do |k,v| ke = "#{k}=" o.__send__(ke, v) if respond_to?(ke) end end end
A fault-tolerent version of to_proc.
It works just like to_proc, but the block will make sure# the object responds to the assignment.
CREDIT: Trans
[ show source ]
# File lib/core/facets/hash/to_proc.rb, line 31 def to_proc_with_reponse lambda do |o| self.each do |k,v| ke = "#{k}=" o.__send__(ke, v) if respond_to?(ke) end end end
A method to convert a Hash into a Struct.
h = {:name=>"Dan","age"=>33,"rank"=>"SrA","grade"=>"E4"} s = h.to_struct("Foo")
TODO: Is this robust enough considerd hashes aren‘t ordered?
CREDIT: Daniel Berger
[ show source ]
# File lib/core/facets/hash/to_struct.rb, line 12 def to_struct(struct_name) Struct.new(struct_name,*keys).new(*values) end
A method to convert a Hash into a Struct.
h = {:name=>"Dan","age"=>33,"rank"=>"SrA","grade"=>"E4"} s = h.to_struct("Foo")
TODO: Is this robust enough considerd hashes aren‘t ordered?
CREDIT: Daniel Berger
[ show source ]
# File lib/core/facets/hash/to_struct.rb, line 12 def to_struct(struct_name) Struct.new(struct_name,*keys).new(*values) end
Returns a new hash created by traversing the hash and its subhashes, executing the given block on the key and value. The block should return a 2-element array of the form +[key, value]+.
h = { "A"=>"A", "B"=>"B" } g = h.traverse { |k,v| [k.downcase, v] } g #=> { "a"=>"A", "b"=>"B" }
TODO: Contrast these to recursibely —we may not need both.
TODO: Testing value to see if it is a Hash also catches subclasses of Hash.
This is probably not the right thing to do and should catch Hashes only (?) CREDIT: Trans
[ show source ]
# File lib/core/facets/hash/traverse.rb, line 18 def traverse(&b) inject({}) do |h,(k,v)| v = ( Hash === v ? v.traverse(&b) : v ) nk, nv = b[k,v] h[nk] = nv #( Hash === v ? v.traverse(base,&b) : nv ) h end end
Returns a new hash created by traversing the hash and its subhashes, executing the given block on the key and value. The block should return a 2-element array of the form +[key, value]+.
h = { "A"=>"A", "B"=>"B" } g = h.traverse { |k,v| [k.downcase, v] } g #=> { "a"=>"A", "b"=>"B" }
TODO: Contrast these to recursibely —we may not need both.
TODO: Testing value to see if it is a Hash also catches subclasses of Hash.
This is probably not the right thing to do and should catch Hashes only (?) CREDIT: Trans
[ show source ]
# File lib/core/facets/hash/traverse.rb, line 18 def traverse(&b) inject({}) do |h,(k,v)| v = ( Hash === v ? v.traverse(&b) : v ) nk, nv = b[k,v] h[nk] = nv #( Hash === v ? v.traverse(base,&b) : nv ) h end end
In place version of traverse, which traverses the hash and its subhashes, executing the given block on the key and value.
h = { "A"=>"A", "B"=>"B" } h.traverse! { |k,v| [k.downcase, v] } h #=> { "a"=>"A", "b"=>"B" } CREDIT: Trans
[ show source ]
# File lib/core/facets/hash/traverse.rb, line 36 def traverse!(&b) self.replace( self.traverse(&b) ) end
In place version of traverse, which traverses the hash and its subhashes, executing the given block on the key and value.
h = { "A"=>"A", "B"=>"B" } h.traverse! { |k,v| [k.downcase, v] } h #=> { "a"=>"A", "b"=>"B" } CREDIT: Trans
[ show source ]
# File lib/core/facets/hash/traverse.rb, line 36 def traverse!(&b) self.replace( self.traverse(&b) ) end
Iterates through each pair and updates a the hash in place. This is formally equivalent to mash! But does not use mash to accomplish the task. Hence update_each is probably a touch faster.
CREDIT: Trans
[ show source ]
# File lib/core/facets/hash/update.rb, line 23 def update_each # :yield: dup.each do |k,v| update(yield(k,v)) end self end
Iterates through each pair and updates a the hash in place. This is formally equivalent to mash! But does not use mash to accomplish the task. Hence update_each is probably a touch faster.
CREDIT: Trans
[ show source ]
# File lib/core/facets/hash/update.rb, line 23 def update_each # :yield: dup.each do |k,v| update(yield(k,v)) end self end
Iterate over hash updating just the keys.
h = {:a=>1, :b=>2} h.update_keys{ |k| "#{k}!" } h #=> { "a!"=>1, "b!"=>2 } CREDIT: Trans
[ show source ]
# File lib/core/facets/hash/update.rb, line 38 def update_keys #:yield: if block_given? keys.each { |old_key| store(yield(old_key), delete(old_key)) } else to_enum(:update_keys) end end
Iterate over hash updating just the keys.
h = {:a=>1, :b=>2} h.update_keys{ |k| "#{k}!" } h #=> { "a!"=>1, "b!"=>2 } CREDIT: Trans
[ show source ]
# File lib/core/facets/hash/update.rb, line 38 def update_keys #:yield: if block_given? keys.each { |old_key| store(yield(old_key), delete(old_key)) } else to_enum(:update_keys) end end
Iterate over hash updating just the values.
h = {:a=>1, :b=>2} h.update_values{ |v| v+1 } h #=> { a:=>2, :b=>3 } CREDIT: Trans
[ show source ]
# File lib/core/facets/hash/update.rb, line 54 def update_values #:yield: if block_given? each{ |k,v| store(k, yield(v)) } else to_enum(:update_values) end end
Iterate over hash updating just the values.
h = {:a=>1, :b=>2} h.update_values{ |v| v+1 } h #=> { a:=>2, :b=>3 } CREDIT: Trans
[ show source ]
# File lib/core/facets/hash/update.rb, line 54 def update_values #:yield: if block_given? each{ |k,v| store(k, yield(v)) } else to_enum(:update_values) end end
Weave is a very uniqe hash operator. I is designed to merge to complex hashes in according to sensible, regular pattern. The effect is akin to inheritance.
Two hashes are weaved together to produce a new hash. The two hashes need to be compatible according to the following rules for each node:
<tt> hash, hash => hash (recursive +) hash, array => error hash, value => error array, hash => error array, array => array + array array, value => array << value value, hash => error value, array => array.unshift(valueB) value1, value2 => value2 </tt>
Here is a basic example:
h1 = { :a => 1, :b => [ 1 ], :c => { :x => 1 } } => {:b=>[1], :c=>{:x=>1}, :a=>1} h2 = { :a => 2, :b => [ 2 ], :c => { :x => 2 } } => {:b=>[2], :c=>{:x=>2}, :a=>2} h1.weave(h2) => {:b=>[1, 2], :c=>{:x=>2}, :a=>2}
Weave follows the most expected pattern of unifying two complex hashes. It is especially useful for implementing overridable configuration schemes.
CREDIT: Thomas Sawyer
[ show source ]
# File lib/core/facets/hash/weave.rb, line 40 def weave(h) raise ArgumentError, "Hash expected" unless h.kind_of?(Hash) s = self.clone h.each { |k,node| node_is_hash = node.kind_of?(Hash) node_is_array = node.kind_of?(Array) if s.has_key?(k) self_node_is_hash = s[k].kind_of?(Hash) self_node_is_array = s[k].kind_of?(Array) if self_node_is_hash if node_is_hash s[k] = s[k].weave(node) elsif node_is_array raise ArgumentError, 'Incompatible hash addition' #self[k] = node else raise ArgumentError, 'Incompatible hash addition' #self[k] = node end elsif self_node_is_array if node_is_hash raise ArgumentError, 'Incompatible hash addition' #self[k] = node elsif node_is_array s[k] += node else s[k] << node end else if node_is_hash raise ArgumentError, 'Incompatible hash addition' #self[k] = node elsif node_is_array s[k].unshift( node ) else s[k] = node end end else s[k] = node end } s end
Weave is a very uniqe hash operator. I is designed to merge to complex hashes in according to sensible, regular pattern. The effect is akin to inheritance.
Two hashes are weaved together to produce a new hash. The two hashes need to be compatible according to the following rules for each node:
<tt> hash, hash => hash (recursive +) hash, array => error hash, value => error array, hash => error array, array => array + array array, value => array << value value, hash => error value, array => array.unshift(valueB) value1, value2 => value2 </tt>
Here is a basic example:
h1 = { :a => 1, :b => [ 1 ], :c => { :x => 1 } } => {:b=>[1], :c=>{:x=>1}, :a=>1} h2 = { :a => 2, :b => [ 2 ], :c => { :x => 2 } } => {:b=>[2], :c=>{:x=>2}, :a=>2} h1.weave(h2) => {:b=>[1, 2], :c=>{:x=>2}, :a=>2}
Weave follows the most expected pattern of unifying two complex hashes. It is especially useful for implementing overridable configuration schemes.
CREDIT: Thomas Sawyer
[ show source ]
# File lib/core/facets/hash/weave.rb, line 40 def weave(h) raise ArgumentError, "Hash expected" unless h.kind_of?(Hash) s = self.clone h.each { |k,node| node_is_hash = node.kind_of?(Hash) node_is_array = node.kind_of?(Array) if s.has_key?(k) self_node_is_hash = s[k].kind_of?(Hash) self_node_is_array = s[k].kind_of?(Array) if self_node_is_hash if node_is_hash s[k] = s[k].weave(node) elsif node_is_array raise ArgumentError, 'Incompatible hash addition' #self[k] = node else raise ArgumentError, 'Incompatible hash addition' #self[k] = node end elsif self_node_is_array if node_is_hash raise ArgumentError, 'Incompatible hash addition' #self[k] = node elsif node_is_array s[k] += node else s[k] << node end else if node_is_hash raise ArgumentError, 'Incompatible hash addition' #self[k] = node elsif node_is_array s[k].unshift( node ) else s[k] = node end end else s[k] = node end } s end
Operator for reverse_merge.
CREDIT: Trans
[ show source ]
# File lib/core/facets/hash/op.rb, line 36 def |(other) other.merge(self) end
Operator for reverse_merge.
CREDIT: Trans
[ show source ]
# File lib/core/facets/hash/op.rb, line 36 def |(other) other.merge(self) end