使用jq将JSON数组转换为父子嵌套结构的优化方案问询
优化jq过滤器实现动态父子嵌套树形结构
给定一个包含id、parent字段的JSON数组(父元素type均为2),元素数量和父子关系不固定,需要用jq v1.7.1将其转换为父子嵌套的树形结构。你现有的代码已经能完成基本的节点嵌套,但存在两个可优化点:需要手动过滤结果中的null元素,且最终节点保留了多余的parent字段。
优化后的jq过滤器
reduce .[] as $o ( { parents: {}, roots: [] }; # 预处理节点:移除parent字段,初始化children数组 ($o | del(.parent) + { children: [] }) as $processedNode | if $o.parent == $o.id then # 根节点:直接加入roots集合,同时存入映射表 .roots += [$processedNode] | .parents[$o.id] = $processedNode else # 非根节点:先存入映射表 .parents[$o.id] = $processedNode # 若父节点已存在,将当前节点挂载到父节点的children,并从映射表移除 | if .parents[$o.parent] then .parents[$o.parent].children += [$processedNode] | del(.parents[$o.id]) else empty end end ) | .roots
关键优化点说明
- 自动清理无效条目
改用{ parents: {}, roots: [] }作为reduce的初始状态:parents临时存储未找到父节点的节点,roots直接收集根节点(parent == id的节点)。非根节点找到父节点后会立即从parents中移除,最终直接返回roots数组,无需后续手动过滤null元素。 - 构建阶段移除冗余字段
在处理每个节点时,先用del(.parent)移除多余的parent字段,再初始化children数组,确保最终生成的树形结构中没有冗余字段,无需后续额外处理。 - 逻辑简化与可读性提升
明确拆分根节点和非根节点的处理逻辑,避免原代码中重复的节点赋值操作,逻辑更清晰易懂,也更容易维护扩展。
额外说明
- 该方案支持任意深度的父子嵌套,无论节点数量和层级关系如何变化;
- 如果需要显式校验父节点的
type为2,可以在处理前添加过滤逻辑,例如在reduce前加上map(if .parent != .id then select(.type == 2) else . end)(根据实际需求调整)。
内容的提问来源于stack exchange,提问作者paoloschi
相关产品推荐
相关产品推荐

