45}, 2 => {"inner" => 46}, "inner" => 4...">

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"

+4
source share
5 answers
 def fx x.inject({}) do |m, (k, v)| v = fv if v.is_a? Hash # note, arbitrarily recursive m[k] = v unless k == 'inner' m end end pfh 

Update: slightly improved ...

 def fx x.is_a?(Hash) ? x.inject({}) do |m, (k, v)| m[k] = fv unless k == 'inner' m end : x end 
+6
source

Indeed, this is what is rejected! for:

 def f! x x.reject!{|k,v| 'inner' == k} if x.is_a? Hash x.each{|k,v| f! x[k]} end 
+5
source

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"}} 
+2
source
 def except_nested(x,key) case x when Hash then x = x.inject({}) {|m, (k, v)| m[k] = except_nested(v,key) unless k == key ; m } when Array then x.map! {|e| except_nested(e,key)} end x end 
+1
source

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

0
source

Source: https://habr.com/ru/post/1413426/


All Articles