Ruby: Removing all instances of a specific key from a hash hash
I have a hash like
h = {1 => {"inner" => 45}, 2 => {"inner" => 46}, "inner" => 47}
How to delete each pair containing the key "internal"?
You can see that some โinnerโ pairs are mapped directly to h
, while others are mapped in pairs to h
Please note that I want to remove only the โinternalโ pairs, so if I call the bulk delete method in the above hash, I should get
h = {1 => {}, 2 => {}}
Since these pairs do not have the key == "internal"
Here is what I came up with:
class Hash def deep_reject_key!(key) keys.each {|k| delete(k) if k == key || self[k] == self[key] } values.each {|v| v.deep_reject_key!(key) if v.is_a? Hash } self end end
Works for Hash or HashWithIndifferentAccess
> x = {'1' => 'cat', '2' => { '1' => 'dog', '2' => 'elephant' }} => {"1"=>"cat", "2"=>{"1"=>"dog", "2"=>"elephant"}} > y = x.with_indifferent_access => {"1"=>"cat", "2"=>{"1"=>"dog", "2"=>"elephant"}} > x.deep_reject_key!(:"1") => {"1"=>"cat", "2"=>{"1"=>"dog", "2"=>"elephant"}} > x.deep_reject_key!("1") => {"2"=>{"2"=>"elephant"}} > y.deep_reject_key!(:"1") => {"2"=>{"2"=>"elephant"}}
A similar answer, but this is a whitelist approach. For ruby โโ1.9+
# recursive remove keys def deep_simplify_record(hsh, keep) hsh.keep_if do |h, v| if v.is_a?(Hash) deep_simplify_record(v, keep) else keep.include?(h) end end end hash = {:a => 1, :b => 2, :c => {:a => 1, :b => 2, :c => {:a => 1, :b => 2, :c => 4}} } deep_simplify_record(hash, [:b, :c]) # => {:b=>2, :c=>{:b=>2, :c=>{:b=>2, :c=>4}}}
Also listed are some other methods that I would like to use for hashes. https://gist.github.com/earlonrails/2048705