有没有办法使用ruby hashie gem进行深度删除?

时间:2019-02-21 02:38:54

标签: ruby

因此,hashie具有deep_find_all方法,可以用来查找嵌套哈希中的所有键,但是有一种方法可以进行深度删除或深度查找,从而以可以删除键的方式返回键

我看到了可以将哈希转换为mashie并进行删除的地方,但它似乎并没有超出顶层。

我正在尝试从JSON中删除所有包含时间戳的键,以便可以比较来自两个不同主机的结果。我已经实现了一种方法,但是似乎有点笨拙,而深度删除将只是凭单。

谢谢 克雷格

1 个答案:

答案 0 :(得分:1)

您可以创建通用的红宝石方法:

def hash_recurse(hash, &blk)
  hash.each do |key, val|
    blk.call(hash, key, val)
    if val.is_a?(Hash)
      hash_recurse(val, &blk)
    end
  end
end

然后,您可以传递任何块,包括要删除的块:

hash = {
  a: {
    timestamp: 123,
    key: "val1"
  },
  b: {
    timestamp: 456,
    foo: "val2"
  }
}

hash_recurse(hash) do |_hash, key, val|
  _hash.delete(key) if key == :timestamp
end

puts hash
# => {:a=>{:key=>"val1"}, :b=>{:foo=>"val2"}}

这与深度优先搜索本质上是相同的。例如,如果您想提取散列中所有键及其子散列的“路径”,则可以对其进行修改以保留当前路径的记录:

def hash_recurse(hash, path=[], &blk)
  hash.each do |key, val|
    new_path = path + [key]
    blk.call(hash, key, val, new_path)
    if val.is_a?(Hash)
      hash_recurse(val, new_path, &blk)
    end
  end
end

并像这样获取路径:

paths = []
hash_recurse(hash) do |_hash, key, val, path|
  paths << path
end

paths.each { |path| puts path.join(",") }
# =>
#    a
#    a,timestamp
#    a,key
#    b
#    b,timestamp
#    b,foo