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

如何用jq实现键与数组值反转?解决reduce值覆盖问题

用JQ实现数组值的键值反转(避免值被覆盖)

需求描述

将输入数据中Contents数组的每个唯一元素作为输出对象的键,对应的值是所有包含该元素的原始数据的Id组成的数组。

示例输入

[
  {
    "Id": "abc",
    "Contents": [
      "foo",
      "bar"
    ]
  },
  {
    "Id": "def",
    "Contents": [
      "foo",
      "baz",
      "ding"
    ]
  },
  {
    "Id": "ghi",
    "Contents": [
      "bar",
      "dang",
      "baz"
    ]
  }
]

期望输出

{
  "foo": [
    "abc",
    "def"
  ],
  "bar": [
    "abc",
    "ghi"
  ],
  "baz": [
    "def",
    "ghi"
  ],
  "ding": [
    "def"
  ],
  "dang": [
    "ghi"
  ]
}

尝试的错误代码

map(.Id as $Id
  | .Contents
  | map({key: ., value: [$Id]})
  | from_entries
)
| reduce .[] as $item ({}; . * $item)

当前错误输出

{
  "foo": [
    "def"
  ],
  "bar": [
    "ghi"
  ],
  "baz": [
    "ghi"
  ],
  "ding": [
    "def"
  ],
  "dang": [
    "ghi"
  ]
}

问题原因与解决方案

问题根源

使用*合并对象时,若键重复会直接覆盖旧值,而非合并数组,导致之前的Id被后面的覆盖。

正确JQ代码

reduce .[] as $item ({};
  $item.Id as $id
  | $item.Contents[] as $content
  | .[$content] += [$id]
)

代码说明

  1. 外层reduce遍历输入数组的每个元素,初始值为空对象{}
  2. 提取当前元素的Id存入变量$id
  3. 遍历当前元素Contents数组的每个内容项$content
  4. 通过.[$content] += [$id]将$id追加到对应键的数组中:若键不存在则自动创建新数组,存在则直接追加元素

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 19:44:58