используйте jq, чтобы вернуть логическое значение, если более одного ключа имеет указанное значение - PullRequest
3 голосов
/ 03 мая 2019

У меня есть блоб JSON. Он содержит очередь элементов для обработки. Я использую JQ для фильтрации. Каждый объект в этой очереди имеет ключ downloadId. Я могу вернуть список объектов, где downloadId имеет определенное значение с помощью этого фильтра:

.[] | select((.downloadId) == "ABCA01479FCAB77D0A8A5C499D5ABAA147E97B47")

Но что мне действительно нужно, так это логическое значение, которое будет возвращать true, если в очереди более одного объекта с этим значением для downloadId. Я просматривал руководство по jq, но я не совсем уверен, как это сделать. Я могу попробовать использовать any

any(.[]; .downloadId == "ABCA01479FCAB77D0A8A5C499D5ABAA147E97B47")

но возвращает true, если существует один экземпляр этого значения, но не более одного.

Вот капля:

[
  {
    "sizeleft": 805679928.0,
    "timeleft": "00:00:00",
    "estimatedCompletionTime": "2019-05-03T17:30:31.370856Z",
    "status": "Paused",
    "trackedDownloadStatus": "Ok",
    "statusMessages": [],
    "downloadId": "1C2DE46A5B4258BE7AC47FEFAE71432897417126",
    "id": 1065601863
  },
  {
    "sizeleft": 836459293.0,
    "timeleft": "00:00:00",
    "estimatedCompletionTime": "2019-05-03T17:30:31.370864Z",
    "status": "Paused",
    "trackedDownloadStatus": "Ok",
    "statusMessages": [],
    "downloadId": "728084A13FD172FED437C6AE503A8CF4A8D317AE",
    "id": 1177597916
  },
  {
    "sizeleft": 836459293.0,
    "timeleft": "00:00:00",
    "estimatedCompletionTime": "2019-05-03T17:30:31.370864Z",
    "status": "Paused",
    "trackedDownloadStatus": "Ok",
    "statusMessages": [],
    "downloadId": "ABCA01479FCAB77D0A8A5C499D5ABAA147E97B47",
    "id": 1177597916
  }
]

1 Ответ

4 голосов
/ 03 мая 2019

Чтобы получить эффективное решение, давайте определим repeated/2, чтобы проверить, встречается ли данное значение более одного раза в потоке:

def repeated(stream; $value):
  label $done
  | foreach stream as $x (0;
       if $x == $value then  . + 1 else . end;
       if . == 2 then true, break $done else empty end)
  // false;

Ключевым моментом здесь, конечно, является выход из цикла при повторном обнаружении значения.

Решение

С учетом вышеизложенного решение будет:

repeated(.[] | .downloadId; "ABCA01479FCAB77D0A8A5C499D5ABAA147E97B47")
...