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

如何使用jq reduce将数组转为分组对象及报错排查

使用jq的reduce方法分组JSON数组报错问题

输入JSON数组

[
  {"cat": "low", "value": "1"},
  {"cat": "med", "value": "2"},
  {"cat": "med", "value": "3"}
]

期望输出

{
  "low": [
    {
      "cat": "low",
      "value": "1"
    }
  ],
  "med": [
    {
      "cat": "med",
      "value": "2"
    },
    {
      "cat": "med",
      "value": "3"
    }
  ]
}

编写的jq代码

reduce .[] as $curr ({}; 
                     $curr.cat as $category |                         # 存储当前分类,比如"low"
                     .[$category] as $currArray |                     # 获取当前分类对应的数组
                     $currArray + [($curr)] as $newCategoryArray |    # 将当前对象加入数组
                     . + {($category): ($newCategoryArray)}           # 更新累加器
                    )

报错信息

jq: error (at <stdin>:5): array ([{"cat":"me...) and object ({"low":[{"c...) cannot be added
exit status 5

注:输入数组中分类唯一时代码可正常运行,仅分类重复时触发报错。


问题原因

报错的核心是第一次处理重复分类时,$currArray的值为null。当首次处理med分类时,累加器里还没有med这个键,.[$category]会返回null;而jq中null + [数组]会把null当作空对象处理,导致$newCategoryArray变成对象与数组非法相加的结果,后续执行. + {($category): ...}时就会触发类型不匹配的报错。

修正后的代码

只需在获取$currArray时,用// []将null替换为空数组即可:

reduce .[] as $curr ({}; 
  $curr.cat as $category |
  (.[$category] // []) as $currArray |  # 若分类不存在,用空数组替代null
  $currArray + [$curr] as $newCategoryArray |
  . + {($category): $newCategoryArray}
)

或者用更简洁的写法,直接利用+=操作符自动处理空值:

reduce .[] as $curr ({}; .[$curr.cat] += [$curr])

代码解释

  • // []:jq的空值合并操作,当目标键不存在时返回空数组,保证后续数组拼接操作合法。
  • 简洁写法中,.[$curr.cat] += [$curr]会自动处理键不存在的情况:若分类未在累加器中,jq会先创建该键并赋值为空数组,再执行追加操作,逻辑与前者一致但更精简。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 09:35:16