如何用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
相关产品推荐
相关产品推荐

