递归解析JSON对象 按规则过滤移除不符合条件节点的方法
嵌套组织层级JSON过滤实现方案
核心思路
这个过滤逻辑不能用从上到下的顺序遍历,因为父节点是否保留依赖于子树中是否存在available=True的节点,因此采用后序遍历的方式处理:先递归处理所有子节点,再根据子节点处理结果和当前节点的available字段判断是否保留当前节点。
保留判断规则
处理每个节点时按以下逻辑判断:
- 先递归遍历当前节点下的所有子
org,收集所有需要保留的子节点,得到过滤后的子节点列表 - 如果当前节点
available值为True:直接保留当前节点,输出时仅保留org_name和过滤后的子节点列表 - 如果当前节点
available值为False:- 若过滤后的子节点列表不为空,说明子树中存在需要保留的可用节点,当前节点作为父级必须保留
- 若过滤后的子节点列表为空,说明当前分支下无任何可用节点,直接丢弃当前节点
代码实现(Python)
def filter_org(node): # 先递归处理所有下级组织 filtered_children = [] for child in node.get("orgs", []): child_res = filter_org(child) if child_res is not None: filtered_children.append(child_res) # 判断当前节点是否需要保留 if node["available"]: # 自身为可用节点,直接保留 return { "org_name": node["org_name"], "orgs": filtered_children } else: # 自身不可用,但子树存在需要保留的节点,连带保留当前节点 if filtered_children: return { "org_name": node["org_name"], "orgs": filtered_children } # 自身不可用且无需要保留的子节点,返回None代表丢弃 return None # 调用测试 if __name__ == "__main__": raw_data = { "org_name": "1", "available": True, "orgs": [ {"org_name": "2", "available": False, "orgs": []}, {"org_name": "3", "available": False, "orgs": []}, {"org_name": "4", "available": True, "orgs": []}, {"org_name": "5", "available": False, "orgs": [ {"org_name": "6", "available": False, "orgs": []}, {"org_name": "7", "available": False, "orgs": []}, {"org_name": "8", "available": False, "orgs": [ {"org_name": "9", "available": False, "orgs": []}, {"org_name": "10", "available": True, "orgs": []} ]} ]} ] } import json result = filter_org(raw_data) # 若需要和示例输出完全一致(最下层叶子节点省略空orgs字段)可启用以下格式化逻辑 # 若业务要求所有节点必须携带orgs字段,删除该段代码即可 def format_leaf(node): if not node["orgs"]: del node["orgs"] else: for child in node["orgs"]: format_leaf(child) return node result = format_leaf(result) print(json.dumps(result, indent=2, ensure_ascii=False))
结果验证
运行上述代码输出的结果和给出的期望结构完全匹配:
- 无可用后代的不可用节点(2、3、6、7、9)全部被过滤
- 自身可用的节点(1、4、10)全部保留
- 存在可用后代的不可用节点(5、8)作为父级被连带保留
注:其他编程语言实现逻辑完全一致,只需要按照后序遍历的思路改写对应语法即可。
内容的提问来源于stack exchange,提问作者Tony Frank
相关产品推荐
相关产品推荐

