【问题标题】:How to remove nested keys from a hash list in Rails如何从 Rails 中的哈希列表中删除嵌套键
【发布时间】:2013-05-23 18:04:15
【问题描述】:

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

   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 方法,但找不到任何东西。是否甚至可以将嵌套键传递给此方法,或者我应该使用其他方法从我的哈希列表中删除嵌套哈希键?

【问题讨论】:

标签: ruby-on-rails hash nested key except


【解决方案1】:

试试

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

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

【讨论】:

  • 感谢您的建议。但它会抛出 NoMethodError: undefined method `except' for "value1":String
【解决方案2】:

怎么样

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

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

呃。

【讨论】:

  • 这很好用,但你能解释一下这个符号吗?关键字“Hash”如何获取数组索引,为什么我们要将每个元素映射到 [k,v] 或 [k,v.except("nested_key2")] 的数组?
  • 参见ruby-doc.org/core-2.0/Hash.html#method-c-5B-5D,这是创建散列的标准方法。它接受 key,value,key,value,... 的列表或关联 key=>value, key=>value,... 或嵌套数组,我们在这里使用。
【解决方案3】:

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

在此转载并附注:

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"}}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-08
    • 2021-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-31
    • 1970-01-01
    相关资源
    最近更新 更多