Module: DR::CoreExt::Hash
- Defined in:
- lib/drain/ruby_ext/core_ext.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#key which does that, but the difference here is that we flatten Enumerable values.
-
#keyed_value(key, sep: "/") ⇒ Object
take a key of the form ploum/plam/plim and return self[:ploum][:plam][:plim].
-
#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/drain/ruby_ext/core_ext.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/drain/ruby_ext/core_ext.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#key which does that, but the difference here is that we flatten Enumerable values
72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/drain/ruby_ext/core_ext.rb', line 72 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]
96 97 98 99 100 101 102 103 104 |
# File 'lib/drain/ruby_ext/core_ext.rb', line 96 def keyed_value(key, sep: "/") r=self.dup return r if key.empty? key.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 |
#sort_all ⇒ Object
sort the keys and the values of the hash
86 87 88 89 90 91 92 |
# File 'lib/drain/ruby_ext/core_ext.rb', line 86 def sort_all r=::Hash[self.sort] r.each do |k,v| r[k]=v.sort end return r end |