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

如何用jq将双属性为键的对象数组转换为索引嵌套对象

使用jq将Turborepo dry-run输出转换为嵌套索引对象

我需要把Turborepo --dry-run=json 输出预处理后的JSON对象数组,转换为以package为一级键、task为二级键,其余字段为值的嵌套索引对象。尝试用reduce实现时遇到了语法和逻辑错误:ChatGPT给出的代码报"Cannot index string with string 'task'",模仿JS写法的代码也出现语法错误。我用jqplay测试代码,但对jq基础语法掌握不足,无法正确构建嵌套对象。

输入示例:

{
  "package": "@nullvoxpopuli/dev",
  "task": "_syncPnpm",
  "local": false,
  "remote": false,
  "status": "MISS",
  "timeSaved": 0
}
{
  "package": "@nullvoxpopuli/dev",
  "task": "test",
  "local": false,
  "remote": false,
  "status": "MISS",
  "timeSaved": 0
}

期望输出:

{
  "@nullvoxpopuli/dev": {
    "_syncPnpm": {
      "local": false,
      "remote": false,
      "status": "MISS",
      "timeSaved": 0
    },
    "test": {
      "local": false,
      "remote": false,
      "status": "MISS",
      "timeSaved": 0  
    }
  }
}

正确的jq实现代码

使用reduce遍历所有输入对象,逐步构建嵌套结构,同时移除package和task字段:

reduce .[] as $item ({};
  .[$item.package] += {
    ($item.task): ($item | del(.package, .task))
  }
)

代码解释

  • reduce .[] as $item ({}; ...):遍历输入的每个JSON对象($item),从空对象{}开始累积结果。
  • .[$item.package] += ...:以当前对象的package值为键,向对应的一级对象中添加内容。若该键不存在,会自动创建新对象。
  • ($item.task): ($item | del(.package, .task)):以当前对象的task值为二级键,值为移除package和task字段后的剩余属性。
  • del(.package, .task):剔除不需要保留的键,仅保留local、remote等目标字段。

测试方式

将输入的JSON数据保存为文件(如input.json),执行命令:

jq -n -f transform.jq input.json

也可直接在jqplay中粘贴输入数据和上述jq代码进行测试。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 19:55:18