Class: Hash
- Defined in:
- lib/more/facets/random.rb,
lib/core/facets/hash/at.rb,
lib/core/facets/hash/op.rb,
lib/more/facets/command.rb,
lib/more/facets/ostruct.rb,
lib/core/facets/hash/new.rb,
lib/more/facets/snapshot.rb,
lib/core/facets/conversion.rb,
lib/core/facets/hash/merge.rb,
lib/core/facets/hash/rekey.rb,
lib/core/facets/hash/slice.rb,
lib/core/facets/hash/weave.rb,
lib/more/facets/openobject.rb,
lib/core/facets/hash/delete.rb,
lib/core/facets/hash/insert.rb,
lib/core/facets/hash/keyize.rb,
lib/core/facets/hash/select.rb,
lib/core/facets/hash/update.rb,
lib/core/facets/hash/inverse.rb,
lib/core/facets/hash/iterate.rb,
lib/core/facets/hash/has_keys.rb,
lib/core/facets/hash/traverse.rb,
lib/core/facets/enumerable/mash.rb
Direct Known Subclasses
LRUCache, Multiton::InstanceMutex, OpenObject, Settings::SettingCollection, SyncHash
Class Method Summary collapse
-
.autonew(*args) ⇒ Object
Hash which auto initializes it’s children.
-
.zipnew(keys, values) ⇒ Object
Creates a new hash from two arrays –a keys array and a values array.
Instance Method Summary collapse
-
#&(other) ⇒ Object
Hash intersection.
-
#*(other) ⇒ Object
Like merge operator ‘+’ but merges in reverse order.
-
#+(other) ⇒ Object
Operator for #merge.
-
#-(other) ⇒ Object
Operator for remove hash paris.
-
#<<(other) ⇒ Object
Can be used like update, or passed as two-element [key,value] array.
-
#alias!(newkey, oldkey) ⇒ Object
Modifies the receiving Hash so that the value previously referred to by oldkey is also referenced by newkey; oldkey is retained in the Hash.
-
#argumentize(args_field = nil) ⇒ Object
Turn a hash into arguments.
-
#delete_unless ⇒ Object
Inverse of #delete_if.
-
#delete_values(*values) ⇒ Object
Minor modification to Ruby’s Hash#delete method allowing it to take multiple keys.
-
#delete_values_at(*keys, &yld) ⇒ Object
Minor modification to Ruby’s Hash#delete method allowing it to take multiple keys.
-
#diff(h2) ⇒ Object
Difference comparison of two hashes.
-
#each_with_key(&yld) ⇒ Object
(also: #each_with_index)
Each with key is like each_pair but reverses the order the parameters to [value,key] instead of [key,value].
-
#except(*less_keys) ⇒ Object
Returns a new hash less the given keys.
-
#except!(*less_keys) ⇒ Object
Replaces hash with new hash less the given keys.
-
#has_keys?(*check_keys) ⇒ Boolean
Returns true or false whether the hash contains the given keys.
-
#has_only_keys?(*check_keys) ⇒ Boolean
Returns true if the hash contains only the given keys, otherwise false.
-
#insert(name, value) ⇒ Object
As with #store but only if the key isn’t already in the hash.
-
#inverse ⇒ Object
Create a “true” inverse hash by storing mutliple values in Arrays.
-
#join(pair_divider = '', elem_divider = '') ⇒ Object
Like Array#join but specialized to Hash.
-
#mash!(&yld) ⇒ Object
(also: #graph!, #collate!)
In place version of #mash.
-
#normalize_keys(&block) ⇒ Object
Converts all keys in the Hash accroding to the given block.
-
#normalize_keys!(&block) ⇒ Object
Synonym for Hash#normalize_keys, but modifies the receiver in place (and returns it).
-
#pairs_at(*keys) ⇒ Object
Return a new hash with the specified entries.
-
#rand_key ⇒ Object
Returns a random key.
-
#rand_key! ⇒ Object
(also: #pick_key)
Delete a random key-value pair, returning the key.
-
#rand_pair ⇒ Object
Returns a random key-value pair.
-
#rand_pair! ⇒ Object
(also: #pick_pair)
Deletes a random key-value pair and returns that pair.
-
#rand_value ⇒ Object
(also: #at_rand)
Returns a random hash value.
-
#rand_value! ⇒ Object
(also: #pick, #at_rand!)
Deletes a random key-value pair and returns the value.
-
#rekey(meth = nil, &block) ⇒ Object
Converts all keys in the Hash accroding to the given block.
-
#rekey!(meth = nil, &block) ⇒ Object
Synonym for Hash#rekey, but modifies the receiver in place (and returns it).
-
#replace_each ⇒ Object
Same as #update_each, but deletes the key element first.
- #restore_snapshot(snap) ⇒ Object
-
#reverse_merge(other) ⇒ Object
Allows for reverse merging where its the keys in the calling hash that wins over those in the
other_hash. -
#reverse_merge!(other) ⇒ Object
(also: #reverse_update)
Inplace form of #reverse_merge.
-
#select! ⇒ Object
In-place version of Hash#select.
-
#shuffle ⇒ Object
Returns a copy of the hash with values arranged in new random order.
-
#shuffle! ⇒ Object
Destructive shuffle_hash.
-
#slice(*keep_keys) ⇒ Object
Returns a new hash with only the given keys.
-
#slice!(*keep_keys) ⇒ Object
Replaces hash with a new hash having only the given keys.
-
#stringify_keys(&filter) ⇒ Object
(also: #keys_to_s)
Converts all keys in the Hash to Strings, returning a new Hash.
-
#stringify_keys!(&filter) ⇒ Object
(also: #keys_to_s!)
Synonym for Hash#stringify_keys, but modifies the receiver in place and returns it.
-
#swap!(key1, key2) ⇒ Object
Swap the values of a pair of keys in place.
-
#swapkey!(newkey, oldkey) ⇒ Object
Modifies the receiving Hash so that the value previously referred to by oldkey is referenced by newkey; oldkey is removed from the Hash.
-
#symbolize_keys(&filter) ⇒ Object
(also: #keys_to_sym)
Converts all keys in the Hash to Symbols, returning a new Hash.
-
#symbolize_keys!(&filter) ⇒ Object
(also: #keys_to_sym!)
Synonym for Hash#symbolize_keys, but modifies the receiver in place and returns it.
- #take_snapshot ⇒ Object
-
#to_console ⇒ Object
Convert an array into command line parameters.
-
#to_h ⇒ Object
Return a rehashing of self.
-
#to_openobject ⇒ Object
Convert a Hash into an OpenObject.
-
#to_ostruct ⇒ Object
Turns a hash into a generic object using an OpenStruct.
-
#to_ostruct_recurse(exclude = {}) ⇒ Object
Like to_ostruct but recusively objectifies all hash elements as well.
-
#to_proc ⇒ Object
Constructs a Proc object from a hash such that the parameter of the Proc is assigned the hash keys as attributes.
-
#to_proc_with_reponse ⇒ Object
A fault-tolerent version of #to_proc.
-
#to_struct(struct_name) ⇒ Object
A method to convert a Hash into a Struct.
-
#traverse(&b) ⇒ Object
Returns a new hash created by traversing the hash and its subhashes, executing the given block on the key and value.
-
#traverse!(&b) ⇒ Object
In place version of traverse, which traverses the hash and its subhashes, executing the given block on the key and value.
-
#update_each ⇒ Object
Iterates through each pair and updates a the hash in place.
-
#update_keys ⇒ Object
Iterate over hash updating kust the keys.
-
#update_values ⇒ Object
Iterate over hash updating just the values.
- #variablize_keys(of_class = nil) ⇒ Object
-
#variablize_keys!(of_class = nil) ⇒ Object
Synonym for Hash#keys_to_string, but modifies the receiver in place (and returns it).
-
#weave(h) ⇒ Object
Weave is a very uniqe hash operator.
-
#|(other) ⇒ Object
Operator for #reverse_merge.
Class Method Details
.autonew(*args) ⇒ Object
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
20 21 22 23 24 |
# File 'lib/core/facets/hash/new.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 |
.zipnew(keys, values) ⇒ Object
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
35 36 37 38 39 |
# File 'lib/core/facets/hash/new.rb', line 35 def self.zipnew(keys,values) # or some better name h = {} keys.size.times{ |i| h[ keys[i] ] = values[i] } h end |
Instance Method Details
#&(other) ⇒ Object
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
32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/core/facets/hash/op.rb', line 32 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 |
#*(other) ⇒ Object
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
93 94 95 |
# File 'lib/core/facets/hash/op.rb', line 93 def *(other) other.merge(self) end |
#+(other) ⇒ Object
Operator for #merge.
CREDIT: Trans
57 58 59 |
# File 'lib/core/facets/hash/op.rb', line 57 def +(other) merge(other) end |
#-(other) ⇒ Object
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 mathcing keys are removed.
CREDIT: Trans
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/core/facets/hash/op.rb', line 67 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 |
#<<(other) ⇒ Object
Can be used like update, or passed as two-element [key,value] array.
CREDIT: Trans
8 9 10 11 12 13 14 |
# File 'lib/core/facets/hash/op.rb', line 8 def <<(other) if other.respond_to?(:to_ary) self.store(*other) else update(other) end end |
#alias!(newkey, oldkey) ⇒ Object
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
59 60 61 62 |
# File 'lib/core/facets/hash/rekey.rb', line 59 def alias!( newkey, oldkey ) self[newkey] = self[oldkey] if self.has_key?(oldkey) self end |
#argumentize(args_field = nil) ⇒ Object
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" } ]
332 333 334 335 336 337 338 339 340 341 |
# File 'lib/more/facets/command.rb', line 332 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 |
#delete_unless ⇒ Object
Inverse of #delete_if.
CREDIT: Daniel Schierbeck
11 12 13 |
# File 'lib/core/facets/hash/delete.rb', line 11 def delete_unless #:yield: delete_if{ |key, value| ! yield(key, value) } end |
#delete_values(*values) ⇒ Object
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
24 25 26 |
# File 'lib/core/facets/hash/delete.rb', line 24 def delete_values(*values) keys.map{ |key| delete(key) if values.include?(fetch(key)) } end |
#delete_values_at(*keys, &yld) ⇒ Object
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
42 43 44 |
# File 'lib/core/facets/hash/delete.rb', line 42 def delete_values_at(*keys, &yld) keys.map{|key| delete(key, &yld) } end |
#diff(h2) ⇒ Object
Difference comparison of two hashes.
CREDIT: ?
TODO:
- Rewrite #diff to be more readable.
- Rename #diff to #difference or something else?
105 106 107 |
# File 'lib/core/facets/hash/op.rb', line 105 def diff(h2) dup.send(:delete_if){|k,v| h2[k] == v}.send(:merge,h2.dup.send(:delete_if){ |k,v| has_key?(k) }) end |
#each_with_key(&yld) ⇒ Object Also known as: each_with_index
Each with key is like each_pair but reverses the order the parameters to [value,key] instead of [key,value].
CREDIT: Trans
8 9 10 |
# File 'lib/core/facets/hash/iterate.rb', line 8 def each_with_key( &yld ) each_pair{ |k,v| yld.call(v,k) } end |
#except(*less_keys) ⇒ Object
Returns a new hash less the given keys.
24 25 26 |
# File 'lib/core/facets/hash/slice.rb', line 24 def except(*less_keys) slice(*keys - less_keys) end |
#except!(*less_keys) ⇒ Object
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}
35 36 37 38 39 |
# File 'lib/core/facets/hash/slice.rb', line 35 def except!(*less_keys) removed = slice(*less_keys) replace(except(*less_keys)) removed end |
#has_keys?(*check_keys) ⇒ Boolean
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
12 13 14 15 |
# File 'lib/core/facets/hash/has_keys.rb', line 12 def has_keys?(*check_keys) unknown_keys = check_keys - self.keys return unknown_keys.empty? end |
#has_only_keys?(*check_keys) ⇒ Boolean
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
26 27 28 29 |
# File 'lib/core/facets/hash/has_keys.rb', line 26 def has_only_keys?(*check_keys) unknown_keys = self.keys - check_keys return unknown_keys.empty? end |
#insert(name, value) ⇒ Object
As with #store but only if the key isn’t already in the hash.
TODO: Would #store? be a better name?
CREDIT: Trans
10 11 12 13 14 15 16 17 |
# File 'lib/core/facets/hash/insert.rb', line 10 def insert(name, value) if key?(name) false else store(name,value) true end end |
#inverse ⇒ Object
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
15 16 17 18 19 20 21 22 23 24 25 |
# File 'lib/core/facets/hash/inverse.rb', line 15 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 |
#join(pair_divider = '', elem_divider = '') ⇒ Object
Like Array#join but specialized to Hash.
CREDIT: Mauricio Fernandez
142 143 144 145 146 |
# File 'lib/core/facets/conversion.rb', line 142 def join(pair_divider='', elem_divider='') s = [] each_pair { |k,v| s << "#{k}#{pair_divider}#{v}" } s.join(elem_divider) end |
#mash!(&yld) ⇒ Object Also known as: graph!, collate!
In place version of #mash.
NOTE: Hash#mash! is only useful for Hash. It is not generally
applicable to Enumerable.
47 48 49 |
# File 'lib/core/facets/enumerable/mash.rb', line 47 def mash!(&yld) replace(mash(&yld)) end |
#normalize_keys(&block) ⇒ Object
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.normalize_keys{ |k| k.to_s } #=> { "name"=>"Gavin", "wife"=>:Lisa }
foo.inspect #=> { :name =>"Gavin", :wife=>:Lisa }
CREDIT: Trans
CREDIT: Gavin Sinclair
18 19 20 |
# File 'lib/core/facets/hash/keyize.rb', line 18 def normalize_keys( &block ) dup.send(:normalize_keys!, &block) end |
#normalize_keys!(&block) ⇒ Object
Synonym for Hash#normalize_keys, but modifies the receiver in place (and returns it).
foo = { :name=>'Gavin', :wife=>:Lisa }
foo.normalize_keys!{ |k| k.to_s } #=> { "name"=>"Gavin", "wife"=>:Lisa }
foo.inspect #=> { "name"=>"Gavin", "wife"=>:Lisa }
CREDIT: Trans
CREDIT: Gavin Sinclair
31 32 33 34 35 36 37 |
# File 'lib/core/facets/hash/keyize.rb', line 31 def normalize_keys!( &block ) keys.each{ |k| nk = block[k] self[nk]=delete(k) if nk } self end |
#pairs_at(*keys) ⇒ Object
Return a new hash with the specified entries.
{:a=>1,:b=>2}.pairs_at(:a,:c) #=> {:a=>1, :c=>nil}
The later form is equivalent to #pairs_at.
CREDIT: Trans
24 25 26 |
# File 'lib/core/facets/hash/iterate.rb', line 24 def pairs_at( *keys ) keys.inject({}) {|h,k| h[k] = self[k]; h} end |
#rand_key ⇒ Object
Returns a random key.
{:one => 1, :two => 2, :three => 3}.pick_key #=> :three
175 176 177 |
# File 'lib/more/facets/random.rb', line 175 def rand_key keys.at( rand(keys.size) ) end |
#rand_key! ⇒ Object Also known as: pick_key
Delete a random key-value pair, returning the key.
a = {:one => 1, :two => 2, :three => 3}
a.pick_key! #=> :two
a #=> {:one => 1, :three => 3}
185 186 187 188 189 |
# File 'lib/more/facets/random.rb', line 185 def rand_key! k,v = rand_pair delete( k ) return k end |
#rand_pair ⇒ Object
Returns a random key-value pair.
{:one => 1, :two => 2, :three => 3}.pick #=> [:one, 1]
197 198 199 200 |
# File 'lib/more/facets/random.rb', line 197 def rand_pair k = rand_key return k, fetch(k) end |
#rand_pair! ⇒ Object Also known as: pick_pair
Deletes a random key-value pair and returns that pair.
a = {:one => 1, :two => 2, :three => 3}
a.rand_pair! #=> [:two, 2]
a #=> {:one => 1, :three => 3}
208 209 210 211 212 |
# File 'lib/more/facets/random.rb', line 208 def rand_pair! k,v = rand_pair delete( k ) return k,v end |
#rand_value ⇒ Object Also known as: at_rand
Returns a random hash value.
{:one => 1, :two => 2, :three => 3}.rand_value #=> 2
{:one => 1, :two => 2, :three => 3}.rand_value #=> 1
221 222 223 |
# File 'lib/more/facets/random.rb', line 221 def rand_value fetch( rand_key ) end |
#rand_value! ⇒ Object Also known as: pick, at_rand!
Deletes a random key-value pair and returns the value.
a = {:one => 1, :two => 2, :three => 3}
a.at_rand! #=> 2
a #=> {:one => 1, :three => 3}
231 232 233 234 235 |
# File 'lib/more/facets/random.rb', line 231 def rand_value! k,v = rand_pair delete( k ) return v end |
#rekey(meth = nil, &block) ⇒ Object
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
15 16 17 18 |
# File 'lib/core/facets/hash/rekey.rb', line 15 def rekey( meth=nil, &block ) raise ArgumentError, "2 for 1" if meth and block dup.send(:rekey!, meth, &block) end |
#rekey!(meth = nil, &block) ⇒ Object
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
28 29 30 31 32 33 34 35 36 37 |
# File 'lib/core/facets/hash/rekey.rb', line 28 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 |
#replace_each ⇒ Object
Same as #update_each, but deletes the key element first.
CREDIT: Trans
7 8 9 10 11 12 13 |
# File 'lib/core/facets/hash/update.rb', line 7 def replace_each # :yield: dup.each do |k,v| delete(k) update(yield(k,v)) end self end |
#restore_snapshot(snap) ⇒ Object
169 |
# File 'lib/more/facets/snapshot.rb', line 169 def restore_snapshot(snap) replace(snap) end |
#reverse_merge(other) ⇒ Object
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( = {})
.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.
15 16 17 |
# File 'lib/core/facets/hash/merge.rb', line 15 def reverse_merge(other) other.merge(self) end |
#reverse_merge!(other) ⇒ Object Also known as: reverse_update
Inplace form of #reverse_merge.
21 22 23 |
# File 'lib/core/facets/hash/merge.rb', line 21 def reverse_merge!(other) replace(reverse_merge(other)) end |
#select! ⇒ Object
In-place version of Hash#select. The opposite of the built-in Hash#reject!.
CREDIT Gavin Sinclair
CREDIT Noah Gibbs
9 10 11 |
# File 'lib/core/facets/hash/select.rb', line 9 def select! reject! { |k,v| not yield(k,v) } end |
#shuffle ⇒ Object
Returns a copy of the hash with values arranged in new random order.
h = {:a=>1, :b=>2, :c=>3}
h.shuffle_hash #=> {:b=>2, :c=>1, :a>3}
248 249 250 |
# File 'lib/more/facets/random.rb', line 248 def shuffle Hash.zipnew( keys.sort_by{Kernel.rand}, values.sort_by{Kernel.rand} ) end |
#shuffle! ⇒ Object
Destructive shuffle_hash. Arrange the values in a new random order.
h = {:a => 1, :b => 2, :c => 3}
h.shuffle_hash!
h #=> {:b=>2, :c=>1, :a=>3}
259 260 261 |
# File 'lib/more/facets/random.rb', line 259 def shuffle! self.replace( shuffle ) end |
#slice(*keep_keys) ⇒ Object
Returns a new hash with only the given keys.
5 6 7 8 9 10 11 |
# File 'lib/core/facets/hash/slice.rb', line 5 def slice(*keep_keys) h = {} keep_keys.each do |key| h[key] = fetch(key) end h end |
#slice!(*keep_keys) ⇒ Object
Replaces hash with a new hash having only the given keys. This return the hash of keys removed.
16 17 18 19 20 |
# File 'lib/core/facets/hash/slice.rb', line 16 def slice!(*keep_keys) removed = except(*keep_keys) replace(slice(*keep_keys)) removed end |
#stringify_keys(&filter) ⇒ Object Also known as: keys_to_s
Converts all keys in the Hash to Strings, returning a new Hash. With a filter parameter, limits conversion to only a certain selection of keys.
foo = { :name=>'Gavin', :wife=>:Lisa }
foo.stringify_keys #=> { "name"=>"Gavin", "wife"=>:Lisa }
foo.inspect #=> { :name =>"Gavin", :wife=>:Lisa }
CREDIT: Trans
CREDIT: Gavin Sinclair
49 50 51 52 53 54 55 |
# File 'lib/core/facets/hash/keyize.rb', line 49 def stringify_keys( &filter ) if filter normalize_keys{ |k| filter[k] ? k.to_s : nil } else normalize_keys{ |k| k.to_s } end end |
#stringify_keys!(&filter) ⇒ Object Also known as: keys_to_s!
Synonym for Hash#stringify_keys, but modifies the receiver in place and returns it. With a filter parameter, limits conversion to only a certain selection of keys.
foo = { :name=>'Gavin', :wife=>:Lisa }
foo.stringify_keys! #=> { "name"=>"Gavin", "wife"=>:Lisa }
foo.inspect #=> { "name"=>"Gavin", "wife"=>:Lisa }
CREDIT: Trans
CREDIT: Gavin Sinclair
69 70 71 72 73 74 75 |
# File 'lib/core/facets/hash/keyize.rb', line 69 def stringify_keys!( &filter ) if filter normalize_keys!{ |k| filter[k] ? k.to_s : nil } else normalize_keys!{ |k| k.to_s } end end |
#swap!(key1, key2) ⇒ Object
Swap the values of a pair of keys in place.
{:a=>1,:b=>2}.swap!(:a,:b) #=> {:a=>2,:b=>1}
CREDIT: Gavin Sinclair
70 71 72 73 74 75 |
# File 'lib/core/facets/hash/rekey.rb', line 70 def swap!( key1, key2 ) tmp = self[key1] self[key1] = self[key2] self[key2] = tmp self end |
#swapkey!(newkey, oldkey) ⇒ Object
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
90 91 92 93 |
# File 'lib/core/facets/hash/rekey.rb', line 90 def swapkey!( newkey, oldkey ) self[newkey] = self.delete(oldkey) if self.has_key?(oldkey) self end |
#symbolize_keys(&filter) ⇒ Object Also known as: keys_to_sym
Converts all keys in the Hash to Symbols, returning a new Hash. With a filter, limits conversion to only a certain selection of keys.
foo = { :name=>'Gavin', 'wife'=>:Lisa }
foo.symbolize_keys #=> { :name=>"Gavin", :wife=>:Lisa }
foo.inspect #=> { "name" =>"Gavin", "wife"=>:Lisa }
CREDIT: Trans
CREDIT: Gavin Sinclair
89 90 91 92 93 94 95 |
# File 'lib/core/facets/hash/keyize.rb', line 89 def symbolize_keys( &filter ) if filter normalize_keys{ |k| filter[k] ? k.to_sym : nil } else normalize_keys{ |k| k.to_sym } end end |
#symbolize_keys!(&filter) ⇒ Object Also known as: keys_to_sym!
Synonym for Hash#symbolize_keys, but modifies the receiver in place and returns it. With a filter parameter, limits conversion to only a certain selection of keys.
foo = { 'name'=>'Gavin', 'wife'=>:Lisa }
foo.symbolize_keys! #=> { :name=>"Gavin", :wife=>:Lisa }
foo.inspect #=> { :name=>"Gavin", :wife=>:Lisa }
CREDIT: Trans
CREDIT: Gavin Sinclair
115 116 117 118 119 120 121 122 |
# File 'lib/core/facets/hash/keyize.rb', line 115 def symbolize_keys!( &filter ) if filter normalize_keys!{ |k| filter[k] ? k.to_sym : nil } else normalize_keys!{ |k| k.to_sym } end end |
#take_snapshot ⇒ Object
168 |
# File 'lib/more/facets/snapshot.rb', line 168 def take_snapshot() dup end |
#to_console ⇒ Object
Convert an array into command line parameters. The array is accepted in the format of Ruby method arguments –ie. [arg1, arg2, …, hash]
309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 |
# File 'lib/more/facets/command.rb', line 309 def to_console flags = collect do |f,v| m = f.to_s.size == 1 ? '-' : '--' case v when Array v.collect{ |e| "#{m}#{f}='#{e}'" }.join(' ') when true "#{m}#{f}" when false, nil '' else "#{m}#{f}='#{v}'" end end flags.join(" ") end |
#to_h ⇒ Object
Return a rehashing of self.
{"a"=>1,"b"=>2}.to_h #=> {"b"=>2,"a"=>1}
CREDIT: Forian Gross
154 |
# File 'lib/core/facets/conversion.rb', line 154 def to_h; rehash; end |
#to_openobject ⇒ Object
Convert a Hash into an OpenObject.
215 216 217 |
# File 'lib/more/facets/openobject.rb', line 215 def to_openobject OpenObject[self] end |
#to_ostruct ⇒ Object
Turns a hash into a generic object using an OpenStruct.
o = { 'a' => 1 }.to_ostruct
o.a #=> 1
187 188 189 |
# File 'lib/more/facets/ostruct.rb', line 187 def to_ostruct OpenStruct.new(self) end |
#to_ostruct_recurse(exclude = {}) ⇒ Object
Like to_ostruct but recusively objectifies all hash elements as well.
o = { 'a' => { 'b' => 1 } }.to_ostruct_recurse
o.a.b #=> 1
The exclude parameter is used internally to prevent infinite recursion and is not intended to be utilized by the end-user. But for more advance use, if there is a particular subhash you would like to prevent from being converted to an OpoenStruct then include it in the exclude hash referencing itself. Eg.
h = { 'a' => { 'b' => 1 } }
o = h.to_ostruct_recurse( { h['a'] => h['a'] } )
o.a['b'] #=> 1
215 216 217 218 219 220 221 222 223 |
# File 'lib/more/facets/ostruct.rb', line 215 def to_ostruct_recurse(exclude={}) return exclude[self] if exclude.key?( self ) o = exclude[self] = OpenStruct.new h = self.dup each_pair do |k,v| h[k] = v.to_ostruct_recurse( exclude ) if v.respond_to?(:to_ostruct_recurse) end o.__update__(h) end |
#to_proc ⇒ Object
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
168 169 170 171 172 173 174 175 |
# File 'lib/core/facets/conversion.rb', line 168 def to_proc lambda do |o| self.each do |k,v| ke = "#{k}=" o.__send__(ke, v) end end end |
#to_proc_with_reponse ⇒ Object
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
184 185 186 187 188 189 190 191 |
# File 'lib/core/facets/conversion.rb', line 184 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 |
#to_struct(struct_name) ⇒ Object
A method to convert a Hash into a Struct.
h = {:name=>"Dan","age"=>33,"rank"=>"SrA","grade"=>"E4"}
s = h.to_struct("Foo")
CREDIT: Daniel Berger
200 201 202 |
# File 'lib/core/facets/conversion.rb', line 200 def to_struct(struct_name) Struct.new(struct_name,*keys).new(*values) end |
#traverse(&b) ⇒ Object
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" }
CREDIT: Trans
– 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 (?)
++
19 20 21 22 23 24 25 26 |
# File 'lib/core/facets/hash/traverse.rb', line 19 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 |
#traverse!(&b) ⇒ Object
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
37 38 39 |
# File 'lib/core/facets/hash/traverse.rb', line 37 def traverse!(&b) self.replace( self.traverse(&b) ) end |
#update_each ⇒ Object
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
22 23 24 25 26 27 |
# File 'lib/core/facets/hash/update.rb', line 22 def update_each # :yield: dup.each do |k,v| update(yield(k,v)) end self end |
#update_keys ⇒ Object
Iterate over hash updating kust the keys.
h = {:a=>1, :b=>2}
h.update_keys{ |k,v| "#{k}#{v}" }
h #=> { "a1"=>2, "b2"=>3 }
CREDIT: Trans
37 38 39 |
# File 'lib/core/facets/hash/update.rb', line 37 def update_keys #:yield: each{ |k,v| delete(k) ; store(yield(k), v) } end |
#update_values ⇒ Object
Iterate over hash updating just the values.
h = {:a=>1, :b=>2}
h.update_values{ |k,v| v+1 }
h #=> { a:=>2, :b=>3 }
CREDIT: Trans
49 50 51 |
# File 'lib/core/facets/hash/update.rb', line 49 def update_values #:yield: each{ |k,v| store(k, yield(v)) } end |
#variablize_keys(of_class = nil) ⇒ Object
144 145 146 |
# File 'lib/core/facets/hash/keyize.rb', line 144 def variablize_keys( of_class=nil ) self.dup.variablize_keys!( of_class ) end |
#variablize_keys!(of_class = nil) ⇒ Object
Synonym for Hash#keys_to_string, but modifies the receiver in place (and returns it). With a from_class parameter, limits conversion to only a certain class of keys. It defaults to nil which convert any key class.
foo = { :name=>'Gavin', :wife=>:Lisa }
foo.variablize_keys! #=> { "@name"=>"Gavin", "@wife"=>:Lisa }
foo.inspect #=> { "@name"=>"Gavin", "@wife"=>:Lisa }
CREDIT: Trans
CREDIT: David Hansson
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
# File 'lib/core/facets/hash/keyize.rb', line 159 def variablize_keys!( of_class=nil ) raise ArgumentError, "Parameter must be a class" unless of_class.kind_of?(Class) if of_class if of_class self.each_key do |k| if k.respond_to?(:to_s) and k.class == of_class k = k.to_s nk = k[0,1] != '@' ? k : "@#{k}" self[nk]=self.delete(k) end end else self.each_key do |k| if k.respond_to?(:to_s) k = k.to_s nk = k[0,1] != '@' ? k : "@#{k}" self[nk]=self.delete(k) end end end self end |
#weave(h) ⇒ Object
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
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# 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 |
#|(other) ⇒ Object
Operator for #reverse_merge.
CREDIT: Trans
49 50 51 |
# File 'lib/core/facets/hash/op.rb', line 49 def |(other) other.merge(self) end |