如何检查 zsh 数组是否包含给定值?

如何检查 zsh 数组是否包含给定值?

假设我有一个非关联数组,其定义如下

my_array=(foo bar baz)

如何检查数组是否包含给定的字符串?我更喜欢一个可以在块的条件中使用的解决方案if(例如if contains $my_array "something"; then ...)。

答案1

array=(foo bar baz foo)
pattern=f*
value=foo

if (($array[(I)$pattern])); then
  echo array contains at least one value that matches the pattern
fi

if (($array[(Ie)$value])); then
  echo value is amongst the values of the array
fi

$array[(I)foo]foo返回最后一次出现in的索引,$array如果未找到则返回 0。该e标志表示它是exact 匹配而不是模式匹配。

要检查是否$value属于文字值列表,您可以将该值列表传递给匿名函数并在函数体中查找$valuein :$@

if ()(( $@[(Ie)$value] )) foo bar baz and some more; then
  echo "It's one of those"
fi

要知道该值在数组中出现了多少次,可以使用${A:*B}运算符(数组A中也存在于 array 中的元素B):

array=(foo bar baz foo)
value=foo
search=("$value")
(){print -r $# occurrence${2+s} of $value in array} "${(@)array:*search}"

或者对数组元素使用模式匹配:

(){print -r $# occurrence${2+s} of $value in array} "${(M@)array:#$value}"

答案2

如果您有一个数组$my_array并且想知道它是否包含该字符串foo,一种可能的测试是

[[ ${my_array[(ie)foo]} -le ${#my_array} ]]

数组元素的完整、精确值必须是foo;它不是子字符串检查或类似的东西。

如果你想查看变量的值是否$my_string在数组中,请使用

[[ ${my_array[(ie)$my_string]} -le ${#my_array} ]]

这个(ie)语法不是很明显。它的解释是下标标志部分ZSH 手册。这i部分意味着我们正在使用“反向下标”:我们不是像通常那样传递下标并获取值,${my_array[1]}而是传递一个值并询问第一个给出该值的下标。该下标是数字且从 1 开始(数组的第一个元素位于索引 1),这与大多数编程语言使用的约定不同。 in意味着我们想要精确匹配,而不需要扩展模式匹配字符,e例如.(ie)*

如果在数组中找不到该值,${my_array[(ie)foo]将计算第一个索引过了终点数组的索引,因此对于 3 元素数组,它将返回 4。${#my_array}给出数组最后一个元素的索引,因此如果前者小于或等于后者,则给定值存在于数组中的某处。如果你想检查给定的值是否是不是然后将数组中的“小于或等于”更改为“大于”:

[[ ${my_array[(ie)foo]} -gt ${#my_array} ]]

相关内容