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

使用jq v1.6移除同用户名的重复change类型元素并保留原排序

解决jq去重steps数组问题的正确方法

错误原因分析

你之前的命令存在两个核心问题:

  1. .steps[]会把数组拆成单个元素,后续的unique_by无法在数组层面生效,相当于对每个元素单独处理,完全达不到去重效果。
  2. 如果steps数组里有非对象类型的元素(比如字符串、数字),直接访问.value会触发Cannot index string with string "value"的索引错误。
    另外补充:unique_by本身是保留元素第一次出现的实例、剔除后续重复项,是能保留原排序的,但你的写法没用到它的正确场景。

正确命令(两种实现)

实现一:基础版(适合小数据量)

.steps |= reduce .[] as $item (
  [];
  if $item.type == "change" then
    if (IN($item.value; map(select(.type == "change").value))) then
      .
    else
      . + [$item]
    end
  else
    . + [$item]
  end
)

实现二:高效版(适合大数据量)

用数组记录已出现的value,避免每次遍历结果数组做检查:

.steps |= (
  reduce .[] as $item (
    { seen: [], result: [] };
    if $item.type == "change" then
      if $item.value | IN($seen[]) then
        .
      else
        .seen += [$item.value] | .result += [$item]
      end
    else
      .result += [$item]
    end
  ).result
)

命令逻辑说明

两种实现都严格保留原数组顺序,只针对性处理type为"change"的元素:

  1. 遍历steps中的每个元素,非"change"类型的元素直接加入结果数组。
  2. 对于"change"类型的元素,检查其value是否已经在之前保留的同类型元素中出现过:
    • 已出现则跳过,不加入结果数组。
    • 未出现则加入结果数组,并记录该value(高效版)。
  3. 完全兼容数组中的非对象元素,不会触发索引错误。

测试示例

假设输入JSON为:

{
  "steps": [
    { "type": "change", "value": "root" },
    "初始化操作",
    { "type": "change", "value": "admin" },
    { "type": "change", "value": "root" },
    { "type": "modify", "value": "root" }
  ]
}

运行命令后输出:

{
  "steps": [
    { "type": "change", "value": "root" },
    "初始化操作",
    { "type": "change", "value": "admin" },
    { "type": "modify", "value": "root" }
  ]
}

可见重复的type="change"且value="root"元素被移除,其他元素的顺序和内容完全保留。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 04:28:14