递归删除空值的哈希

Hor*_*ice 2 ruby hash

我想删除不同嵌套级别的空哈希。一旦删除了空哈希,我也想删除它的容器哈希。我该怎么做?

这是我想要处理的哈希:

{
  "query"=>{"filtered"=>{
    "query"=>{"bool"=>{}},
    "filter"=>{"query"=>{"query_string"=>{
      "fields"=>[["standard_analyzed_name", "standard_analyzed_message"]],
      "query"=>"Arnold AND Schwarz"
    }}}
  }},
  "sort"=>[{"total_interactions"=>{"order"=>"desc"}}]
}
Run Code Online (Sandbox Code Playgroud)

下面是我没有删除空{"query"=>{"bool"=>{}}部分的代码:

def compactify_hash(main_hash)
  main_hash.each do |key, value|
    if(value.class == Hash && !value.empty?)
      compactify_hash(value)
    elsif(value.class == Hash && value.empty?)
      main_hash.delete(key)
    end
  end
  return main_hash
end
Run Code Online (Sandbox Code Playgroud)

mu *_*ort 5

你在这里有几个问题:

  1. 您可能无意中就地修改散列,compactify_hash!如果您真的想就地修改它,您可能想命名您的方法。

  2. 您的哈希中有数组,但您不会扫描它们以查找空哈希。

  3. 最重要的是,您永远不会检查递归压缩的哈希值以查看压缩它们是否也清空了它们。在这里:

     if(value.class == Hash && !value.empty?)
       compactify_hash(value)
     elsif(value.class == Hash && value.empty?)
       main_hash.delete(key)
     end
    
    Run Code Online (Sandbox Code Playgroud)

你需要检查value.empty? compactify_hash(value)

你可以这样做:

def compactify_hash(main_hash)
  main_hash.each_with_object({}) do |(k, v), h|
    if(v.is_a?(Hash))
      ch = compactify_hash(v)
      h[k] = ch if(!ch.empty?)
    elsif(v.is_a?(Array))
      h[k] = v.map do |e|
        e.is_a?(Hash) ? compactify_hash(e) : e
      end
    else
      h[k] = v
    end
  end
end
Run Code Online (Sandbox Code Playgroud)