Module: DR::CoreExt::Hash
- Defined in:
- lib/dr/ruby_ext/core_modules.rb
Instance Method Summary collapse
-
#deep_merge(other_hash, &block) ⇒ Object
Returns a new hash with +self+ and +other_hash+ merged recursively.
-
#deep_merge!(other_hash, &block) ⇒ Object
Same as +deep_merge+, but modifies +self+.
-
#inverse ⇒ Object
from a hash [values] produce a hash [keys] there is already Hash#invert using Hash#key which does that, but the difference here is that we flatten Enumerable values h=2, plim: 2, plam: 3 h.invert #=> 3=>:plam h.inverse #=> :plim], 3=>[:plam].
-
#keyed_value(key, sep: "/") ⇒ Object
take a key of the form ploum/plam/plim and return self[:ploum][:plam][:plim].
-
#leafs(nodes) ⇒ Object
from a hash [:bar, :baz], bar: [:plum, :qux], then leaf [:foo] returns [:plum, :qux, :baz].
-
#set_keyed_value(key, value, sep: "/", symbolize: true) ⇒ Object
take a key of the form ploum/plam/plim and return self[:ploum][:plam][:plim]=value.
-
#sort_all ⇒ Object
sort the keys and the values of the hash.
Instance Method Details
#deep_merge(other_hash, &block) ⇒ Object
Returns a new hash with +self+ and +other_hash+ merged recursively.
h1 = { x: { y: [4,5,6] }, z: [7,8,9] }
h2 = { x: { y: [7,8,9] }, z: 'xyz' }
h1.deep_merge(h2) #=> {x: {y: [7, 8, 9]}, z: "xyz"}
h2.deep_merge(h1) #=> {x: {y: [4, 5, 6]}, z: [7, 8, 9]}
h1.deep_merge(h2) { |key, old, new| Array.wrap(old) + Array.wrap(new) }
#=> {:x=>{:y=>[4, 5, 6, 7, 8, 9]}, :z=>[7, 8, 9, "xyz"]}
Adapted from active support
33 34 35 |
# File 'lib/dr/ruby_ext/core_modules.rb', line 33 def deep_merge(other_hash, &block) dup.deep_merge!(other_hash, &block) end |
#deep_merge!(other_hash, &block) ⇒ Object
Same as +deep_merge+, but modifies +self+.
38 39 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 |
# File 'lib/dr/ruby_ext/core_modules.rb', line 38 def deep_merge!(other_hash, &block) return unless other_hash other_hash.each_pair do |k,v| tv = self[k] case when tv.is_a?(Hash) && v.is_a?(Hash) self[k] = tv.deep_merge(v, &block) when tv.is_a?(Array) && v.is_a?(Array) if v.length > 0 && v.first.nil? then #hack: if the array begins with nil, we append the new #value rather than overwrite it v.shift self[k] += v else self[k] = block && tv ? block.call(k, tv, v) : v end when tv.nil? && v.is_a?(Array) #here we still need to remove nil (see above) if v.length > 0 && v.first.nil? then v.shift self[k]=v else self[k] = block && tv ? block.call(k, tv, v) : v end else self[k] = block && tv ? block.call(k, tv, v) : v end end self end |
#inverse ⇒ Object
from a hash [values] produce a hash [keys] there is already Hash#invert using Hash#key which does that, but the difference here is that we flatten Enumerable values h=2, plim: 2, plam: 3 h.invert #=> 3=>:plam h.inverse #=> :plim], 3=>[:plam]
74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/dr/ruby_ext/core_modules.rb', line 74 def inverse r={} each_key do |k| values=fetch(k) values=[values] unless values.respond_to?(:each) values.each do |v| r[v]||=[] r[v]<< k end end return r end |
#keyed_value(key, sep: "/") ⇒ Object
take a key of the form ploum/plam/plim and return self[:ploum][:plam][:plim]
98 99 100 101 102 103 104 105 106 |
# File 'lib/dr/ruby_ext/core_modules.rb', line 98 def keyed_value(key, sep: "/") r=self.dup return r if key.empty? key.to_s.split(sep).each do |k| k=k.to_sym if r.key?(k.to_sym) && !r.key?(k) r=r[k] end return r end |
#leafs(nodes) ⇒ Object
from a hash [:bar, :baz], bar: [:plum, :qux], then leaf [:foo] returns [:plum, :qux, :baz]
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/dr/ruby_ext/core_modules.rb', line 125 def leafs(nodes) =[] #prevent loops r=nodes.dup begin s,r=r,r.map do |n| if key?(n) && !.include?(n) << n fetch(n) else n end end.flatten end until s==r r end |
#set_keyed_value(key, value, sep: "/", symbolize: true) ⇒ Object
take a key of the form ploum/plam/plim and return self[:ploum][:plam][:plim]=value
110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/dr/ruby_ext/core_modules.rb', line 110 def set_keyed_value(key,value, sep: "/", symbolize: true) r=self *keys,last=key.to_s.split(sep) keys.each do |k| k=k.to_sym if (symbolize || r.key?(k.to_sym)) and !r.key?(k) r[k]={} unless r.key?(k) r=r[k] end last=last.to_sym if symbolize r[last]=value self end |
#sort_all ⇒ Object
sort the keys and the values of the hash
88 89 90 91 92 93 94 |
# File 'lib/dr/ruby_ext/core_modules.rb', line 88 def sort_all r=::Hash[self.sort] r.each do |k,v| r[k]=v.sort end return r end |