2013-05-28 1 views
5

Ich versuche jetzt für einige Stunden, einen verschachtelten Hash-Schlüssel einer Hash-Liste zu entfernen. Ich sah viele Lösung nicht verschachtelte hashs wich sieht wie folgt aus: es doesnSo entfernen Sie verschachtelte Schlüssel aus einer Hash-Liste in Rails

{"key2"=>"value2"} 

Aber wenn ich versuche zu verwenden, die außer Methode auf einen Hash mit verschachtelten Schlüssel dann:

sample_hash = {"key1" => "value1", "key2" => "value2"} 
    sample_hash.except("key1") 

Dies führt zu arbeite nicht. Hier mein Code:

nested_hash = {"key1"=>"value1", "key2"=>{ 
              "nested_key1"=>"nestedvalue1", 
              "nested_key2"=>"nestedvalue2" 
              } 
       } 

    nested_hash.except("nested_key2") 

Die Ausnahme() -Methode der nested_hash ohne Änderungen zurück. Ich habe nach einer Lösung gesucht, wie ich verschachtelte Hash-Keys an die Except-Methode übergeben kann, aber nichts gefunden habe. Ist es überhaupt möglich, geschachtelte Schlüssel an diese Methode zu übergeben oder sollte ich eine andere Methode verwenden, die einen verschachtelten Hash-Schlüssel aus meiner Hash-Liste löscht?

+1

Vielleicht möchten Sie einen echten Baum, anstatt einen verschachtelten Hash. Sie können sich https://github.com/evolve75/RubyTree, https://github.com/stefankroes/ancestry oder https://github.com/mceachen/closure_tree für Edelsteine ​​ansehen, die für Sie arbeiten könnten. –

Antwort

8

was

Hash[nested_hash.map {|k,v| [k,(v.respond_to?(:except)?v.except("nested_key2"):v)] }] 

=> {"key1"=>"value1", "key2"=>{"nested_key1"=>"nestedvalue1"}} 

igitt.

+0

Es funktioniert! Vielen Dank, das ist, was ich gesucht habe. – user1367922

+0

Das funktioniert großartig, aber könnten Sie diese Notation erklären? Wie nimmt das Schlüsselwort "Hash" einen Array-Index an und warum ordnen wir jedes Element einem Array von [k, v] oder [k, v.except ("nested_key2")] zu? –

+0

siehe http://www.ruby-doc.org/core-2.0/Hash.html#method-c-5B-5D, die Standardmethode zum Erstellen von Hashes. Es akzeptiert entweder eine Liste von Schlüssel, Wert, Schlüssel, Wert, ... oder Assoziationen Schlüssel => Wert, Schlüssel => Wert, ... oder verschachteltes Array, was wir hier verwenden. –

0

my_hash = Hash[nested_hash.map {|k,v| {k=>v.is_a? Array ? v.except("nested_key2") : v}}.map {|key, value| [key, value]}] 

versuchen Aber das scheint zurückgeblieben, ich wünschte, ich begann nie auf diesem Weg, ich bin bereit, ein einfacher Weg zu wetten, gibt es!

+0

Danke für Ihren Vorschlag. aber es wirft einen NoMethodError: undefined Methode 'außer 'für" Wert1 ": String – user1367922

+0

I; ll fügen eine Ausnahme hinzu – RadBrad

0

Die akzeptierte Lösung gilt für das angegebene Szenario. Wenn Sie jedoch nach etwas suchen, das dies für beliebig verschachtelte Hashtabellen ermöglicht, benötigen Sie eine rekursive Lösung. Ich konnte nirgendwo eine passende Lösung finden, also schrieb ich eine here.

hier mit Anmerkungen Abgebildet:

class Hash 
    def except_nested(key) 
    r = Marshal.load(Marshal.dump(self)) # deep copy the hashtable 
    r.except_nested!(key) 
    end 

    def except_nested!(key) 
    self.except!(key) 
    self.each do |_, v| # essentially dfs traversal calling except! 
     v.except_nested!(key) if v.is_a?(Hash) 
    end 
    end 
end 

es dem Hash Klasse hinzugefügt, so dass Sie es auf die gleiche Weise, außer rufen anrufen/außer! irgendwo anders.

t = { a: '1', b: { c: '3', d: '4' } } 

r = t.except_nested(:c) 
# r => {:a=>"1", :b=>{:d=>"4"}} 
# t => {:a=>"1", :b=>{:c=>"3", :d=>"4"}} 

t.except_nested!(:c) 
# t => {:a=>"1", :b=>{:d=>"4"}} 
Verwandte Themen