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

求助:使用JQ筛选并删除嵌套数组含重复项的JSON对象

JQ筛选保留含不同条目的数组对象问题

问题说明

给定JSON数组,需删除所有ratings.q1.all_answers数组元素全重复的顶层对象,仅保留该数组至少包含两种不同元素的对象。

示例输入JSON:

[
{
  "ratings" : {
    "q1" : {
      "all_answers" : [ "a", "a", "a" ],
      "top_answer" : "a"
    },
    "q2" : {
      "all_answers" : [ "no", "yes", "yes" ],
      "top_answer" : "yes"
    }
},
{
  "ratings" : {
    "q1" : {
      "all_answers" : [ "a", "b", "b" ],
      "top_answer" : "a"
    },
    "q2" : {
      "all_answers" : [ "no", "yes", "yes" ],
      "top_answer" : "yes"
    }
},
{
  "ratings" : {
    "q1" : {
      "all_answers" : [ "a", "b", "c" ],
      "top_answer" : "a"
    },
    "q2" : {
      "all_answers" : [ "no", "yes", "yes" ],
      "top_answer" : "yes"
    }
}
]

用户尝试以下命令但无效果:

jq '.[] |= select(.ratings.q1.all_answers | length as $len | $len > ($len - (. | unique | length)))'

问题原因

  1. 逻辑判断错误:原命令中的条件$len > ($len - (. | unique | length))化简后等价于unique数组长度 > 0,所有非空数组都满足该条件,因此所有对象都被保留。
  2. 数组修改方式错误:.[] |= select(...)会将不符合条件的元素设为null而非直接删除,导致数组仍保留这些无效元素。

正确解决方案

以下几种写法均可实现需求:

方案1:通过去重后数组长度判断

判断去重后的数组长度是否大于1(即原数组至少有两种不同元素),用map(select(...))过滤数组:

jq 'map(select(.ratings.q1.all_answers | unique | length > 1))'

方案2:对比原数组与去重后数组长度

通过原数组长度和去重后长度的关系,确认存在不同元素:

jq 'map(select(.ratings.q1.all_answers | (length as $orig_len | unique | length) > 1))'

方案3:检查是否存在与第一个元素不同的元素

利用any()函数判断数组中是否有元素不等于第一个元素,以此确认不全为重复值:

jq 'map(select(.ratings.q1.all_answers | any(. != first)))'

以上命令都会过滤掉q1.all_answers全为重复值的对象,仅保留符合要求的条目。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 11:36:01