首页 > 解决方案 > 检查特定 JSON 键的重复值

问题描述

我将以下 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
123
345

标签: jsonparsingduplicatesjq

解决方案


这是一种使用inputs. 它需要使用 -n 命令行选项调用 jq。这个想法是创建一个字典来记录每个 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 既是字符串又是整数值,则上述程序不会区分1and"1"例子。)

上述字典有时被称为“词袋”(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

推荐阅读