jq in/1 的不一致行为

Deb*_*asu 1 arrays jq

jq 文档中的以下示例按预期工作-

$ echo '[1,2]' | jq 'map(in([0,1]))'
[
  true,
  false
]
Run Code Online (Sandbox Code Playgroud)

但是将值转换为字符串失败了 -

$ echo '["1", "2"]' | jq 'map(in(["0","1"]))'
jq: error (at <stdin>:1): Cannot check whether array has a string key
Run Code Online (Sandbox Code Playgroud)

为了确保这不是 shell 引用问题,我还尝试过——

$ echo "[\"1\", \"2\"]" | jq 'map(in(["0","1"]))'
jq: error (at <stdin>:1): Cannot check whether array has a string key
Run Code Online (Sandbox Code Playgroud)

除此之外,以下代码段也失败了,这可能是由于将 0 强制转换为布尔值 false -

$ echo '[0,1]' | jq 'map(in([1,2]))'       
[
  true,
  true
]

Run Code Online (Sandbox Code Playgroud)

Jef*_*ado 5

你误解了in/1正在做什么。它不是测试一个值是否是数组的成员,而是测试该值是否是对象键的成员。因此,对于数组,需要数字(索引)或对于对象,需要字符串(键)。它has/1与输入完全相同,但交换了输入。

$ jq -n '[0,-1,20,9,16,10] | map(in([range(20;30)]))' # 10 item array
[
  true,
  false,
  false,
  true,
  false,
  false
]
Run Code Online (Sandbox Code Playgroud)
$ jq -n '["foo","bar"] | map(in({foo:1,boo:2,bat:3}))'
[
  true,
  false
]
Run Code Online (Sandbox Code Playgroud)

如果您想测试数组中的成员资格,则没有内置功能,但您可以自己制作。虽然contains/1很接近但不完全是因为它测试字符串是否是子字符串并且不相等。any/2可以用来做到这一点。

def has_value($value):
    any(.[]; . == $value);

def in_array($arr): # swapped input version
    . as $value | any($arr[]; . == $value);
Run Code Online (Sandbox Code Playgroud)

  • 我同意,我更喜欢它的行为类似于 `in` 运算符,因为其他语言通常定义它(例如 python 或 SQL),但它更接近于 javascript 的行为。 (2认同)