E64b3f6a4b0bde29f654eca45fcbb20f

I wanted a Hash#fetch that would return all matches for a particular key in a hash with nested hashes and arrays, and this is what I came up with. I'm pretty new to Ruby, so I can't help but think there's a better way to do it.

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

Refactorings

No refactoring yet !

0f8ba0cdebc6938f4cd0601aeef21621

jes5199

March 21, 2008, March 21, 2008 00:20, permalink

No rating. Login to rate!

well, since we're already reopening standard classes, I thought it might make sense to move the Array logic into class Array. Now we have simple recursion of methods, instead of having to make private functions.

class Hash
  def fetch_all(key)
    return [] if not self.has_key?(key)
    value = self.fetch(key)
    [ value ] + [ value ].fetch_all(key)
  end
end

class Array
  def fetch_all(key)
    self.find_all{|x| x.respond_to? :fetch_all} \
      .map{|x| x.fetch_all(key) } \
      .inject( [] ){|a,b| a + b }
  end
end
Faccb37537ef4619e07bf0da950d725b

clonecd346

May 9, 2011, May 09, 2011 00:30, permalink

No rating. Login to rate!

A great ship asks deep waters.

B1e576484fda09036b44fd5ad4071d4a

Strattera ohne rezept

June 22, 2011, June 22, 2011 14:54, permalink

No rating. Login to rate!


Those who know don’t speak. Those who speak don’t know.

Your refactoring





Format Copy from initial code

or Cancel