You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何自底向上遍历深度嵌套JSON并清理空字段?

问题

需要高效自底向上遍历深度嵌套的JSON,移除所有空字段、值为'-'或'none'的字段。当前自上而下的遍历只能移除最底层的空字段,无法把清空后变成空对象的父字段(比如示例中的tls)也一并移除。

数据示例

{
    "rule": {
        "description": "authentication_failed",
        "category": {
            "action": "denied"
        }
    },
    "tls": {
        "client": {
            "certificate": {
                "subject": "-"
            }
        },
        "server": {
            "certificate": {
                "subject": "-"
            }
        }
    }
}

当前使用代码

def removeEmptyFields(event,h,name)
    h.each do |k,v|
        if (v.is_a?(Hash) || v.is_a?(Array)) && v.to_s != '{}'
            removeEmptyFields(event,v,String.new(name.to_s) << '[' << k.to_s << ']')
        else
            if v == '' || v == '-' || v == 'none' || v.to_s == '{}'
                event.remove(String.new(name.to_s) << '[' << k.to_s << ']')
            end
        end
    end
end

removeEmptyFields event,event.to_hash,'' 

当前输出

{
    "rule": {
        "description": "authentication_failed",
        "category": {
            "action": "denied"
        }
    },
    "tls": {
        "client": {
            "certificate": {}
        },
        "server": {
            "certificate": {}
        }
    }
}

期望结果

tls字段被整体移除,因为其下所有子字段清理后,tls本身变为空对象。


解决方案

核心问题是原代码采用自上而下遍历,先处理父节点再处理子节点,子节点清空后父节点已经处理完毕,无法回头判断是否需要删除。正确思路是自底向上遍历:先处理所有子节点,再检查父节点是否因子节点清空而变成空对象,进而移除。

以下是修改后的Ruby代码,直接操作哈希对象实现自底向上清理:

def clean_hash(hash)
  # 先递归清理所有子哈希和数组
  hash.each do |k, v|
    case v
    when Hash
      clean_hash(v)
      # 子哈希清理后为空则删除当前键
      hash.delete(k) if v.empty?
    when Array
      # 先清理数组里的哈希元素
      v.each { |item| clean_hash(item) if item.is_a?(Hash) }
      # 过滤掉需要移除的元素,空数组也一并删除
      hash[k] = v.reject { |item| item == '' || item == '-' || item == 'none' || (item.is_a?(Hash) && item.empty?) }
      hash.delete(k) if hash[k].empty?
    else
      # 直接移除符合条件的叶子节点
      hash.delete(k) if v == '' || v == '-' || v == 'none'
    end
  end
  hash
end

# 使用示例:假设event是解析后的JSON哈希
cleaned_event = clean_hash(event.to_hash)
# 如需转回JSON对象,可根据使用的库处理,比如:
# cleaned_json = JSON.generate(cleaned_event)

代码说明

  1. 自底向上逻辑:先递归处理所有子节点,子节点清理完成后再判断当前节点是否需要删除。
  2. 哈希处理:子哈希清理后为空,直接删除对应的父键。
  3. 数组处理:先清理数组内的哈希元素,再过滤掉符合移除条件的元素,空数组也会被删除。
  4. 叶子节点判断:直接移除值为''、'-'、'none'的字段。

用这段代码处理示例数据,会得到期望结果:

{
    "rule": {
        "description": "authentication_failed",
        "category": {
            "action": "denied"
        }
    }
}

内容的提问来源于stack exchange,提问作者starrywrites

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 14:05:47