Recursive Hash#fetch

Comments

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
comments powered by Disqus