Skip to content

Instantly share code, notes, and snippets.

@sepastian
Created January 29, 2014 13:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save sepastian/8688143 to your computer and use it in GitHub Desktop.
Save sepastian/8688143 to your computer and use it in GitHub Desktop.
Hash#deep_traverse extends Ruby's Hash class with a method yielding pairs consisting of path and value. Each path consists of a list of keys leading to the last, right-most key.
class Hash
def deep_traverse(&block)
stack = self.map{ |k,v| [ [k], v ] }
while not stack.empty?
key, value = stack.pop
yield(key, value)
if value.is_a? Hash
value.each{ |k,v| stack.push [ key.dup << k, v ] }
end
end
end
end
# d = {:a=>{:b=>{:c=>1}, :d=>2}}
# d.deep_traverse{ |path,value| p [ path, value ] }
# => [[:a], {:b=>{:c=>1}, :d=>2}]
# [[:a, :d], 2]
# [[:a, :b], {:c=>1}]
# [[:a, :b, :c], 1]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment