Skip to content

Instantly share code, notes, and snippets.

@tpinto
Last active August 29, 2015 13:55
Show Gist options
  • Save tpinto/8731084 to your computer and use it in GitHub Desktop.
Save tpinto/8731084 to your computer and use it in GitHub Desktop.
Just like Hash#deep_merge but works with Arrays, applying the default to each element inside it.
class Hash
def deeper_merge(overriding_hash)
ret = self.merge(overriding_hash) do |key, default_val, overriding_val|
if default_val.class == Array and overriding_val.class == Array
resulting_array = []
for little_hash in overriding_val
resulting_array << default_val.first.deeper_merge(little_hash)
end
resulting_array
else
default_val = default_val.to_hash if default_val.respond_to?(:to_hash)
overriding_val = overriding_val.to_hash if overriding_val.respond_to?(:to_hash)
default_val.class.to_s == 'Hash' && overriding_val.class.to_s == 'Hash' ? default_val.deeper_merge(overriding_val) : overriding_val
end
end
return ret
end
end
#> default = {a: 1, b:1, c: [{a:1, b:1}]}
#=> {:a=>1, :b=>1, :c=>[{:a=>1, :b=>1}]}
#
#> default.deeper_merge({b:5, c:[{b:5,c:1},{a:3,c:2},{a:3,b:4,c:2}]})
#=> {:a=>1,
# :b=>5,
# :c=>[{:a=>1, :b=>5, :c=>1}, {:a=>3, :b=>1, :c=>2}, {:a=>3, :b=>4, :c=>2}]}
#
#> default.deeper_merge({b:5, c:[{b:5,c:1},{a:3,c:2},{a:3,b:4,c:2},{}]})
#=> {:a=>1,
# :b=>5,
# :c=>
# [{:a=>1, :b=>5, :c=>1},
# {:a=>3, :b=>1, :c=>2},
# {:a=>3, :b=>4, :c=>2},
# {:a=>1, :b=>1}]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment