使用 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);
我正在尝试使用 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);