2012-05-20 54 views
4

的哈希我有一個像紅寶石:刪除特定鍵的所有實例從哈希

 
h = {1 => {"inner" => 45}, 2 => {"inner" => 46}, "inner" => 47} 

哈希如何刪除每對包含密鑰「內部」?
你可以看到一些「內部」對直接出現在h而其他h

注意成對出現的,我只想要刪除的「內部」對,所以如果我打電話給我的質量上刪除方法上述散,我應該得到

h = {1 => {}, 2 => {}}

由於這些對不具備一鍵== 「內部」

+0

第一刪除「內」選自H,和然後通過所有嵌套散列遞歸和刪除「內」 – MxyL

回答

6
def f x 
    x.inject({}) do |m, (k, v)| 
    v = f v if v.is_a? Hash # note, arbitrarily recursive 
    m[k] = v unless k == 'inner' 
    m 
    end 
end 

p f h 

更新:略有改善...

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

的多線三元與inject'的'塊形式結合使你的改進的解決方案難以閱讀(特別是當你將這些與單字母,不簡單的方法和變量名稱結合使用時)。如果使用if/else而不是三元和有意義的變量名,會更容易一些,如果input.is_a?(Hash) def reject_keys(input,rejected_key) input.inject({})do | hash,(k,v)| 散列[K] = reject_keys(V),除非滿足K == rejected_key 散列 端 別的 輸入 端 端 提出reject_keys(H, 「內」) ''' – jangosteve

5

真的,這是什麼拒絕!是:

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

這裏是我想出了:

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 

工程的哈希或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"}} 
0

類似的答案,但它是一個白名單類型的方法。對於紅寶石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}}} 

此外,這裏還有一些我喜歡用於散列的其他方法。 https://gist.github.com/earlonrails/2048705

1
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 
+0

我已實際需要這種解決方案因爲我也有嵌套數組!非常感謝! –