7

我现在尝试了几个小时来删除哈希列表的嵌套哈希键。我看到许多解决方案非嵌套哈希看起来像这样:

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

这导致:

  {"key2"=>"value2"}

但是,如果我尝试在带有嵌套键的哈希上使用 except 方法,那么它就不起作用了。这是我的代码:

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

  nested_hash.except("nested_key2")

except() 方法返回 nested_hash 而不做任何更改。我一直在寻找一种解决方案,如何将嵌套的哈希键传递给 except 方法,但找不到任何东西。甚至可以将嵌套键传递给此方法,还是应该使用其他方法从我的哈希列表中删除嵌套哈希键?

4

3 回答 3

10

关于什么

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

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

啊。

于 2013-05-28T17:54:15.653 回答
7

接受的解决方案对于给定的场景是有效的,但是如果您正在寻找可以为任意嵌套的哈希表执行此操作的东西,那么您将需要一个递归解决方案。我在任何地方都找不到合适的解决方案,所以我在这里写了一个。

此处转载带有注释:

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

将其添加到Hash类中,以便您可以像调用 except/except 一样调用它!其他任何地方。

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"}}
于 2017-11-15T23:07:48.010 回答
0

尝试

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

但这似乎是错误的,我希望我从来没有走这条路,我愿意打赌有更简单的方法!

于 2013-05-28T17:15:59.217 回答