根据特定条件使用 jq 删除 JSON 数组中的重复对象

Remove duplicate objects in JSON array with jq based on specific criteria

我有以下数据,我希望根据 "run" 键的重复值删除整个对象,同时保留具有最大 "startTime" 编号的对象:

{
  "data": {
    "results": [
      {
        "event": {
          "biking": {
            "startTime": 12,
            "id": "a",
            "run": "x"
          }
        },
        "displayName": "Alex"
      },
      {
        "event": {
          "biking": {
            "startTime": 10,
            "id": "b",
            "run": "x"
          }
        },
        "displayName": "Adam"
      },
      {
        "event": {
          "biking": {
            "startTime": 11,
            "id": "c",
            "run": "y"
          }
        },
        "displayName": "Aaron"
      }
    ]
  }
}

我一直在尝试用 jq 欺骗 unique,但无法完全得到我想要的。我的预期结果是:

{
  "data": {
    "results": [
      {
        "event": {
          "biking": {
            "startTime": 12,
            "id": "a",
            "run": "x"
          }
        },
        "displayName": "Alex"
      },
      {
        "event": {
          "biking": {
            "startTime": 11,
            "id": "c",
            "run": "y"
          }
        },
        "displayName": "Aaron"
      }
    ]
  }
}

我试图使用 unique 因为我只想保留每个 "run": id 中的 1 个,而在更大的列表中我可能有三个 x、两个 y,还有四个 z。在这种情况下,我想根据最大的 "startTime".

保留一个 xyz
  • 下面是使用 reducer 的方法。

const input = {
  "data": {
    "results": [{
        "event": {
          "biking": {
            "startTime": 12,
            "id": "a",
            "run": "x"
          }
        },
        "displayName": "Alex"
      },
      {
        "event": {
          "biking": {
            "startTime": 10,
            "id": "b",
            "run": "x"
          }
        },
        "displayName": "Adam"
      },
      {
        "event": {
          "biking": {
            "startTime": 11,
            "id": "c",
            "run": "y"
          }
        },
        "displayName": "Aaron"
      }
    ]
  }
};
const output = {
  data: {}
};
output.data.results = Object.values(input.data.results.reduce((r, o) => {
  r[o.event.biking.run] =
    (r[o.event.biking.run] &&
      r[o.event.biking.run].event.biking.startTime > o.event.biking.startTime) ? r[o.event.biking.run] : o
  return r
}, {}));
console.log(output);

  • 致谢名单 ->

这是一个简单的 jq 解决方案:

.data.results |=
  (group_by(.event.biking.run)
   | map(max_by(.event.biking.startTime)))

它使用 group_by 按“运行”分组,然后 max_by 到 select 所需的事件。

这行得通

const result = [
  ...new Map(
    obj.data.results.map((item) => [item["event"]["biking"]["run"], item])
  ).values()
];

DEMO

这是基于helprjs removeDuplicates。