'Exclude elements from a hash based on contents of nested hash?

I have the following Ruby hash...

{
  "Aura"=>{"eyes"=>403, "moon"=>134, "burst"=>75, "psych"=>249},
  "Power: Verdure"=>{"max"=>4, "min"=>1}, 
  "Power: Creature"=>{"max"=>3, "min"=>1}, 
  "Iris"=>{"ice"=>208, "sky"=>220, "aqua"=>206, "deep"=>215, "dusk"=>229, "hide"=>213}
}

I want to remove any element whose hash has max and min. The value of max/min doesn't matter. Just the fact that they exist.

Meaning the hash above would turn into...

{
  "Aura"=>{"eyes"=>403, "moon"=>134, "burst"=>75, "psych"=>249},
  "Iris"=>{"ice"=>208, "sky"=>220, "aqua"=>206, "deep"=>215, "dusk"=>229, "hide"=>213}
}

How would I remove those elements?



Solution 1:[1]

As suggested in comments, this can readily be solved by application of Hash#reject and Hash#has_key?.

data = {
  "Aura"=>{"eyes"=>403, "moon"=>134, "burst"=>75, "psych"=>249},
  "Power: Verdure"=>{"max"=>4, "min"=>1}, 
  "Power: Creature"=>{"max"=>3, "min"=>1}, 
  "Iris"=>{"ice"=>208, "sky"=>220, "aqua"=>206, "deep"=>215, "dusk"=>229, "hide"=>213}
}

pruned_data = data.reject { |k, v| v.has_key?("min") && v.has_key?("max") }

If it processes better in your brain, we can #select only hashes that don't contain both of those keys.

pruned_data = data.select { |k, v| !(v.has_key?("min") && v.has_key?("max")) }

There are more clever ways, but this is a very straightforward problem that seems in need of a straightforward solution.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1