Confounding URL typists since 2007.
Recently, I found myself wishing for a recursive version of Hash#fetch that would get all values from a nested hash structure. I looked around for a while, and couldn’t find one, so I made a little mixin called Hash#fetch_all. It returns an array containing all values matching a given key from any level within such a structure. It definitely still feels like it could be improved on, but it works.
class Hash
def fetch_all(key)
results = []
hashfinder = lambda {|h|
arrayfinder = lambda {|a|
a.each do |v|
hashfinder[v] if v.is_a?(Hash)
arrayfinder[v] if v.is_a?(Array)
end
}
if h.has_key?(key)
results << h.fetch(key)
end
h.values.each do |v|
hashfinder[v] if v.is_a?(Hash)
arrayfinder[v] if v.is_a?(Array)
end
}
hashfinder.call(self)
results
end
end