假设我有一个非关联数组,其定义如下
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
标志表示它是e
xact 匹配而不是模式匹配。
要检查是否$value
属于文字值列表,您可以将该值列表传递给匿名函数并在函数体中查找$value
in :$@
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} ]]