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

如何用jq将对象数组合并为单对象,对应键值转为数组

合并JSON数组为键值数组对象

输入JSON

[{
    "first": 12355,
    "second": "abc"
  },{
    "first": 89010,
    "second": "def"
  },{
    "first": 23423,
    "second": "hij"
  },{
    "first": 23456,
    "second": "klm"
  },{
    "first": 11111,
    "second": "nop"
  }]

需求目标

将数组中的所有对象按对应键合并,每个键的值汇总为一个数组,最终得到如下对象:

{
    "first" : [12355,89010,23423,23456,11111],
    "second" : ["abc","def","hij","klm","nop"]
}

你的代码问题分析

你当前的reduce代码存在几个逻辑错误:

  • 变量命名逻辑颠倒:reduce .[] as $final 里的$final应该指代当前遍历的数组元素,而不是最终结果,这会导致后续赋值逻辑混乱
  • 初始空对象的keys为空:(. | keys) as $k 中的.是reduce的初始值{},没有任何键,所以后续的map不会执行任何操作
  • 错误使用map:reduce内部不需要用map来处理,应该直接对每个键进行值的累加操作

正确的jq解决方案

方法一:嵌套reduce(通用适配任意键)

这是最通用的写法,不管输入对象有多少个键,都能自动合并:

reduce .[] as $item ({};
  reduce ($item | keys_unsorted)[] as $key (.;
    .[$key] += [$item[$key]]
  )
)

逻辑说明:

  1. 外层reduce遍历输入数组的每个元素,初始结果为{}
  2. 内层reduce遍历当前元素的所有键(keys_unsorted保留原键顺序)
  3. 把当前元素的键值追加到结果对象对应键的数组中(如果键不存在,会自动创建数组)

方法二:简洁写法(利用transpose)

如果输入的所有对象键的顺序一致,也可以用更简洁的写法:

[map(to_entries)] | transpose | map({key: .[0].key, value: map(.value)}) | from_entries

逻辑说明:

  1. map(to_entries):把每个对象转成[{key: "...", value: ...}]格式的数组
  2. transpose:将数组转置,把相同键的键值对归为一组
  3. 把每组转成{key: "...", value: [所有对应值]}的格式,最后用from_entries转回对象

运行结果

执行上述任意代码,都会得到你预期的目标JSON。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 15:46:11