2013-05-28 18 views
5

ハッシュリストのネストされたハッシュキーを削除するのに数時間かけています。私は多くのソリューションは、ネストされていないhashsのウィッヒは、次のようになりました :Railsのハッシュリストからネストされたキーを削除する方法

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

これは、その結果:

{"key2"=>"value2"} 

しかし、私は、ネストされたキーを持つハッシュにメソッドを除いて使用しようとすると、それはdoesnの仕事はありません。 ここに私のコード:

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

    nested_hash.except("nested_key2") 

ザ・除く()メソッドを変更することなくnested_hashを返します。私は、ネストされたハッシュ・キーをexceptメソッドに渡す方法を探しましたが、何も見つかりませんでした。ネストされたキーをこのメソッドに渡すことも可能ですか?または、ハッシュリストからネストされたハッシュキーを削除する他のメソッドを使用する必要がありますか?

+1

おそらく、ネストされたハッシュではなく、実際のツリーが必要です。あなたに役立つかもしれない宝石については、https://github.com/evolve75/RubyTree、https://github.com/stefankroes/ancestry、またはhttps://github.com/mceachen/closure_treeをご覧ください。 –

答えて

8

何ぐふ

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

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

について。

+0

それは動作します!多くのありがとうございました。 – user1367922

+0

これは素晴らしいですが、この表記法を説明できますか?キーワード "Hash"はどのように配列インデックスを取りますか、なぜ各要素を[k、v]または[k、v.except( "nested_key2")]の配列にマッピングしますか? –

+0

http://www.ruby-doc.org/core-2.0/Hash.html#method-c-5B-5D、ハッシュを作成するための標準的な方法を参照してください。これは、キー、値、キー、値、または関連のキー=>値、キー=>値、またはネストされた配列のいずれかを受け付けます。 –

0

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

を試してみてくださいしかし、これは遅れそうです、私はこの道を始めたことがない、私はもっと簡単な方法がある賭けることを喜んたいです!

+0

あなたの提案のためのthx。 NoMethodErrorをスローします: "value1"のための 'except ':文字列 – user1367922

+0

私は例外を追加します – RadBrad

0

与えられたシナリオで有効な解決策はありますが、任意にネストされたハッシュテーブルに対してこれを行う何かを探しているなら、再帰的解決策が必要になります。私はどこでも適切なソリューションを見つけることができませんでしたので、私はhereと書きました。

は注釈をここに再現:Hashクラスに追加する

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 

あなたは除き/除いて呼び出すのと同じ方法で呼び出すことができるように!どこか他の。

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"}} 
関連する問題