使用 select 将对象列入白名单

Whitelisting objects using select

我正在尝试使用 jq 提供的 contains 函数来过滤列表。 我的输入,

[1, 2, 3, 4, 5]

我有一个 "whitelist":

[3, 4, 7]

我需要通过白名单过滤输入列表。 预期输出

[3, 4]

我能够过滤比较单个项目:

jq --compact-output --null-input '[1,2,3,4,5] | map(select(. | contains(3)))'
[3]

我试过这个:

$ jq --compact-output --null-input '[1,2,3,4,5] | map(select([3,4,7] | contains([.])))'
[]
$

这里[3,4,7] | contains([.])有意提出问题:

is [.] a sublist of list [3,4,7]?

但它不起作用。我错过了什么?

如何使用白名单进行过滤

已将 contains 更改为 inside,它现在似乎可以工作了:

$ jq --compact-output --null-input '[1,2,3,4,5] | map(select([.] | inside([3,4,7])))'
[3,4]
$

您要与 contains 一起使用的过滤器是:

map(. as $x | select([3,4,7] | contains([$x])))

您的尝试使用 .不正确。

使用index/1

对于此类问题,使用 index/1 可能比 contains 或其逆 inside 更好。原因源于语义和效率方面的考虑。

如果白名单以 $whitelist 的形式提供并且您想使用 map(select(...)),则合适的过滤器为:

map( . as $x | select($whitelist|index($x)))

对于长数组,这当然是非常低效的。对于这样的数组,您几乎肯定会想看看替代方案,例如使用 bsearch(二进制搜索)或 JSON 对象(散列)。

默认值:

index/1 的当前实现对于目前的目的而言并不理想,但速度很快,因为它是用 C 语言编写的。这是一个假设 any/2 可用的替代定义:

def ix(x): any(.[]; .==x);