【问题标题】:Getting a list of keys based on another property in json with jq使用 jq 获取基于 json 中另一个属性的键列表
【发布时间】:2015-10-28 11:48:29
【问题描述】:

我正在尝试为 JSON 创建一个 jq 过滤器,类似于 How to filter an array of objects based on values in an inner array with jq? - 但即使使用它作为基础似乎也没有给我想要的结果。

这是我的示例 json

[{"id":"0001","tags":["one","two"]},{"id":"0002", "tags":["two"]}]

我想返回一个 ID 列表,其中标签包含“one”(不是部分字符串匹配,而是完整元素匹配)。

我尝试了一些变体,但无法正确过滤。

. - map(select(.resources[] | contains("one"))) | .[] .id

返回"0001","0002"

也尝试过... .resources[].one)) | ...,但在尝试按“一”过滤时总是得到完整列表并期望只得到0001

我在哪里过滤错误? (有大约 30 分钟的 jq 经验,所以如果很明显,请原谅我的无知 :)

【问题讨论】:

    标签: arrays json indexof jq


    【解决方案1】:
    map(select(.tags | index("one")) | .id)
    

    由于您的问题描述表明您要检查数组是否包含“一”,因此使用 index 是最简单的。

    更新

    2017 年 1 月 30 日,添加了名为 IN 的内置函数,用于有效测试 JSON 实体是否包含在流中。它还可以用于有效地测试数组中的成员资格。在本例中,相关用法为:

    map(select(.tags as $tags | "one" | IN($tags[])) | .id)
    

    如果你的jq没有IN/1,那么只要你的jq有first/1,你就可以使用这个等价的定义:

    def IN(s): . as $in | first(if (s == $in) then true else empty end) // false;
    

    (实际上,index/1 通常足够快,但目前(jq 1.5 和至少到 2017 年 7 月的版本)的实现并不理想。)

    【讨论】:

    • 我没有看到index 有预定义的功能。查看文档,看起来in 可能是一个有用的函数。但是,使用 in 会给我带来错误 - error: in is not defined。 jq --version 是 1.3
    • 下载 jq 1.4 和索引作品。结果证明我没有正确地期待我的输出,containsindex 给出了相同的结果:与我的期望相反。我得到一个不包含指定标签的 ID 列表。
    • 我的表达式开头有一个-。当我放弃它并按原样使用您的表达时,它实际上确实有效@peak。将答案标记为正确,感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-17
    相关资源
    最近更新 更多