jq中,如何选择数组中至少包含一个值的对象(交集非空)

问题描述 投票:0回答:3

我有这样的输入:

{ "prop": ["apple", "banana"] }
{ "prop": ["kiwi", "banana"] }
{ "prop": ["cherry", "orange"] }

如何打印 prop 至少包含奇异果和橙色之一的对象?

(有趣的值列表不止 2 个,所以我想以某种方式利用

any
函数。)

我尝试过以下方法

jq 'select(any(.prop[] | contains(["kiwi", "orange"])))' < input.json

以及上述的各种变体,但无法找出正确的表达方式。

json select jq any
3个回答
2
投票

如果记住其签名,则可以最轻松地使用内置函数

any
的面向流的版本:

def any(generator; condition):

所以我们被引导到:

select( any( .prop[]; . == "kiwi" or . == "orange" ))

或更简洁地说:

select( any(.prop[]; IN("kiwi", "orange")))

白名单

如果感兴趣的值以 JSON 数组形式提供,例如 $whitelist,您可以通过用

$whitelist[]
替换显式值流来调整上述内容:

select( any(.prop[]; IN($whitelist[]) ))

2
投票

我认为您正在寻找

IN/2
。它是使用 any
 
实现的,但更容易掌握。

select(IN(.prop[]; "kiwi", "orange"))

在线演示


0
投票

上述答案在 jq 1.7 中对我有用,但在 jq 1.6 中失败了(这是 2024 年 2 月在 GitHub Actions ubuntu-latest 运行程序上预安装的内容,我不希望在每个 CI 期间安装更好的东西而影响性能)运行)。

这是我想出的在 1.6 和 1.7 中都能正确且一致地工作的方法:

def intersects(a; b):
  any(a[] as $aElem | b | index($aElem));

使用方法如下:

intersects(["a", "b", "c"]; ["c", "d", "e"]) # true

intersects(["a", "b", "c"]; ["d", "e", "f"]) # false
© www.soinside.com 2019 - 2024. All rights reserved.