Recently, while adding missing functionality for the i18n-js gem I’ve stumbled into a problem. I needed to have a method to “deep reject” keys in the hash. There are some examples in the wild doing that, but they all solve this problem by adding a new method to the Hash class. I wanted a generic method, which would take the hash as an argument.
After some head scratching, tinkering and tweaking, I’ve come up with a correct solution (at least I think it’s correct). Here it is:
def self.deep_reject(hash, &block) hash.each_with_object({}) do |(k, v), memo| unless block.call(k, v) if v.is_a?(Hash) memo[k] = deep_reject(v, &block) else memo[k] = v end end end end
You use it like this:
hash = {:a => {:b => 1, :c => 2}} result = deep_reject(hash) { |k, v| k == :b } result # => {:a => {:c => 2}}