Проверьте наличие повторяющихся значений для конкретного ключа JSON - PullRequest
0 голосов
/ 31 декабря 2018

У меня есть следующие записи JSON, хранящиеся в контейнере

    {"memberId":"123","city":"New York"}
    {"memberId":"234","city":"Chicago"}
    {"memberId":"345","city":"San Francisco"}
    {"memberId":"123","city":"New York"}
    {"memberId":"345","city":"San Francisco"}

Я ищу, чтобы проверить, есть ли дублирование memberId - в идеале вернуть true / false, а затем также вернуть дублированные значения.

Желаемый вывод:

true
123
345

1 Ответ

0 голосов
/ 31 декабря 2018

Вот эффективный подход с использованием inputs.Это требует вызова jq с параметром командной строки -n.Идея состоит в том, чтобы создать словарь, который будет вести подсчет каждого строкового значения memberId.

Словарь может быть создан следующим образом:

reduce (inputs|.memberId|tostring) as $id ({}; .[$id] += 1)

Таким образом, чтобы создать индикатор истинного / ложного, а затем дубликаты, если они есть, вы можете написать:

reduce (inputs|.memberId|tostring) as $id ({}; .[$id] += 1)
| to_entries
| map(select(.value > 1))
| (length > 0), .[].key

(Если известно, что все значения .memberId являются строками, то, конечно, вызов tostring можно отбросить. И наоборот, если .memberId является как строковым, так и целочисленным, то вышеуказанная программа не будет дифференцироватьсямежду вхождениями 1 и "1", например.)

bow

Вышеупомянутый словарь иногда называют «мешком слов» (https://en.wikipedia.org/wiki/Bag-of-words_model). Это приводит куниверсальная функция:

def bow(stream): 
  reduce stream as $word ({}; .[($word|tostring)] += 1);

Теперь решение можно записать более кратко:

bow(inputs.memberId)
| to_entries
| map(select(.value > 1))
| (length > 0), .[].key

Только для значений, имеющих дубликаты, можно написать более эффективный запрос:

bow(inputs.memberId)
| keys_unsorted[] as $k
| select(.[$k] > 1)
| $k
...