-
Notifications
You must be signed in to change notification settings - Fork 0
/
class.Hash.extend.rb
50 lines (44 loc) · 1.63 KB
/
class.Hash.extend.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
class Hash
def keys_nested
result_a = [ ]
self.each_pair do | k, v |
# puts "k = #{k}, v = #{v}, v.class = #{v.class}"
if ( v.is_a?( Array )) then
a = v.map do | e |
if ( e.is_a?( Hash ) ) then
e.keys_nested
else
e
end
end
result_a << k
result_a << a if ( a.length > 0 )
elsif ( v.is_a?( Hash ) ) then
result_a << k
result_a << v.keys_nested
else
result_a << k
end
end
return result_a
end
alias_method :deep_keys, :keys_nested # Seems like "nested" is more common than "deep"
def merge_nested(second)
# https://stackoverflow.com/a/30225093
merger = proc { |_, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : Array === v1 && Array === v2 ? v1 | v2 : [:undefined, nil, :nil].include?(v2) ? v1 : v2 }
merge(second.to_h, &merger)
end
alias_method :deep_merge, :merge_nested # Seems like "nested" is more common than "deep"
# Next 2: https://gist.github.com/steveevers/9d584aed053b9b31467101807462a94c
def except_nested(key)
r = Marshal.load(Marshal.dump(self))
r.except_nested!(key)
end
def except_nested!(key)
self.reject!{|k, v|k == key}
self.each do |_, v|
v.except_nested!(key) if v.is_a?(Hash)
v.map!{|obj| obj.except_nested!(key) if obj.is_a?(Hash)} if v.is_a?(Array)
end
end
end