Skip to content

Instantly share code, notes, and snippets.

@yuroyoro
Created March 26, 2015 04:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yuroyoro/6a531e52eed0a03b8e18 to your computer and use it in GitHub Desktop.
Save yuroyoro/6a531e52eed0a03b8e18 to your computer and use it in GitHub Desktop.
Hash#deep_slice
# Hash#deep_slice
#
# h = {
# :a => 1,
# :b => 2,
# :c => {
# :ca => 31,
# :cb => 32,
# :cc => 33
# },
# :d => {
# :da => {
# :daa => 411,
# :dab => 412
# },
# :db => {
# :dba => 421
# }
# },
# :e => nil
# }
#
#
# h.deep_slice(:a, :e)
# {
# :a => 1,
# :e => nil
# }
#
# h.deep_slice(:a, :c => [:ca, :cc])
# {
# :a => 1,
# :c => {
# :ca => 31,
# :cc => 33
# }
# }
#
# h.deep_slice(:d => [{:da => :dab}, {:db => :dba}])
# {
# :d => {
# :da => {
# :dab => 412
# },
# :db => {
# :dba => 421
# }
# }
# }
#
# h.deep_slice(:b=> :x,:e => :y)
# {
# :b => 2,
# :e => nil
# }
#
class Hash
def deep_slice(*keys)
worker = ->(hash, key, acc) {
return hash unless hash.is_a? Hash
case key
when Hash then key.inject(acc){|h, (k, sk)| h.merge(k => worker.(hash[k], sk, {})) }
when Array then key.inject(acc){|h, k| h.merge(worker.(hash, k, {})) }
else acc.merge(hash.slice(key))
end
}
worker.(self, keys, {})
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment