Module: HashOp::Deep
- Defined in:
- lib/hash_op/deep.rb
Class Method Summary collapse
- .build_with_segments(segments, value) ⇒ Object
-
.fetch(hash, path) ⇒ Object
Examples: h = {b: {c: 1}} HashOp::Deep.fetch(h, :a) # => :b=>{:c=>1} HashOp::Deep.fetch(h, :‘a.b’) # => :c=>1 HashOp::Deep.fetch(h, :‘a.b.c’) # => 1 HashOp::Deep.fetch(h, [:a]) # => :b=>{:c=>1} HashOp::Deep.fetch(h, [:a, :b, :c]) # => 1 HashOp::Deep.fetch(h, :‘b.c.a’) # => nil.
- .fetch_with_deep_key(hash, deep_key) ⇒ Object
- .fetch_with_segments(hash, segments) ⇒ Object
-
.merge(hash, path, value) ⇒ Object
Examples: h = {} h = HashOp::Deep.merge(h, :a, 1) => { :a => 1 } h = HashOp::Deep.merge(h, :‘a.b’, 2) => { :a => { :b => 2 } h = HashOp::Deep.merge(h, :b, 3) => { :a => { :b => 2 }, :b => 3 }.
- .merge_with_deep_key(hash, deep_key, value) ⇒ Object
- .merge_with_segments(hash, segments, value) ⇒ Object
-
.paths(hash) ⇒ Object
Example: hash = { a: { :b => 1, ‘c’ => 2 }, d: 0 } HashOp::Deep.paths(hash) => [[:a, :b], [:a, ‘c’ ], [:d]].
Class Method Details
.build_with_segments(segments, value) ⇒ Object
126 127 128 129 |
# File 'lib/hash_op/deep.rb', line 126 def build_with_segments(segments, value) return value if segments.empty? { segments.first => build_with_segments(segments[1..-1], value) } end |
.fetch(hash, path) ⇒ Object
19 20 21 22 23 24 25 26 27 28 |
# File 'lib/hash_op/deep.rb', line 19 def fetch(hash, path) fail ArgumentError, "First argument must be an Hash (was #{hash})" unless hash.is_a?(Hash) if path.class.in? [String, Symbol] fetch_with_deep_key(hash, path) elsif path.is_a? Array fetch_with_segments(hash, path) else fail ArgumentError, 'Invalid attribute, must be a String or an Array' end end |
.fetch_with_deep_key(hash, deep_key) ⇒ Object
71 72 73 74 75 |
# File 'lib/hash_op/deep.rb', line 71 def fetch_with_deep_key(hash, deep_key) segments = deep_key.to_s.split('.') segments.map!(&:to_sym) if deep_key.is_a? Symbol fetch_with_segments(hash, segments) end |
.fetch_with_segments(hash, segments) ⇒ Object
78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/hash_op/deep.rb', line 78 def fetch_with_segments(hash, segments) return hash if segments.empty? result = hash[segments.first] if result.is_a? Hash fetch_with_segments(result, segments[1..-1]) elsif result.is_a? Array result.map do |item| fetch_with_segments(item, segments[1..-1]) end else result end end |
.merge(hash, path, value) ⇒ Object
Examples:
h = {}
h = HashOp::Deep.merge(h, :a, 1)
=> { :a => 1 }
h = HashOp::Deep.merge(h, :'a.b', 2)
=> { :a => { :b => 2 }
h = HashOp::Deep.merge(h, :b, 3)
=> { :a => { :b => 2 }, :b => 3 }
39 40 41 42 43 44 45 46 47 48 |
# File 'lib/hash_op/deep.rb', line 39 def merge(hash, path, value) fail ArgumentError, 'First argument must be an Hash' unless hash.is_a? Hash if path.class.in? [String, Symbol] merge_with_deep_key(hash, path, value) elsif path.is_a? Array merge_with_segments(hash, path, value) else raise 'Invalid attribute, must be a String or an Array' end end |
.merge_with_deep_key(hash, deep_key, value) ⇒ Object
94 95 96 97 98 |
# File 'lib/hash_op/deep.rb', line 94 def merge_with_deep_key(hash, deep_key, value) segments = deep_key.to_s.split('.') segments.map!(&:to_sym) if deep_key.is_a? Symbol merge_with_segments(hash, segments, value) end |
.merge_with_segments(hash, segments, value) ⇒ Object
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/hash_op/deep.rb', line 101 def merge_with_segments(hash, segments, value) current_segment = segments.first remaining_segments = segments[1..-1] return value if segments.empty? current_value = hash[current_segment] new_value = ( if remaining_segments.length > 0 if current_value.is_a? Hash merge_with_segments(current_value, remaining_segments, value) elsif current_value.is_a? Array current_value.map do |item| merge_with_segments(item, remaining_segments, value) end else build_with_segments remaining_segments, value end else value end ) hash.merge current_segment => new_value end |
.paths(hash) ⇒ Object
Example:
hash = { a: { :b => 1, 'c' => 2 }, d: 0 }
HashOp::Deep.paths(hash)
=> [[:a, :b], [:a, 'c' ], [:d]]
55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/hash_op/deep.rb', line 55 def paths(hash) r = [] hash.each do |key, value| if value.is_a?(Hash) paths(value).each do |deep_key| r << [key] + Array(deep_key) end else r << Array(key) end end r.uniq end |