如何用jq将递归下降结果收集到单个数组?求助解决方案
当然可以用jq实现这个需求!你提到的flatten确实是解决方案的一部分,但之前报错是因为递归遍历过程中产生了null值,导致flatten无法处理。另外,你需要把同一个node下的所有topics聚合到一个数组里,而不是拆分出多条重复name的结果,下面是具体的解决方法:
正确的jq表达式
.data.search.edges[].node | { name, topics: [..|.topics?] | map(select(. != null)) | flatten }
为什么这个能解决问题?
我来拆解每一步的作用:
- 定位到每个节点:
.data.search.edges[].node先遍历所有edges里的node对象,这是处理的基础。 - 递归收集所有topics:
[..|.topics?]用递归下降操作符..遍历当前node的所有嵌套层级,topics?会匹配所有名为topics的字段(加?是为了避免找不到该字段时抛出错误),最后把这些结果包裹成一个数组。 - 过滤无效的null值:
map(select(. != null))这一步是关键!之前你用flatten报错就是因为数组里混进了null,现在把这些null全部过滤掉,确保后续操作的都是有效的数组或元素。 - 扁平化数组:
flatten把收集到的嵌套topics数组展开成一个一维数组,这样同一个node下的所有topics就都集中在一个数组里了。
可选:给topics去重
如果你的数据中存在重复的topic条目,可以在最后加上unique来去重,让结果更整洁:
.data.search.edges[].node | { name, topics: [..|.topics?] | map(select(. != null)) | flatten | unique }
这样处理后,每个node都会输出一个包含name和聚合后topics数组的对象,完全符合你想要的效果。
内容的提问来源于stack exchange,提问作者xpt
相关产品推荐
相关产品推荐

