In Bash, what is the simplest way to test if an array contains a certain value?
Here's my take on this.
I'd rather not use a bash for loop if I can avoid it, as that takes time to run. If something has to loop, let it be something that was written in a lower level language than a shell script.
function array_contains { # arrayname value
local -A _arr=()
local IFS=
eval _arr=( $(eval printf '[%q]="1"\ ' "\${$1[@]}") )
return $(( 1 - 0${_arr[$2]} ))
}
This works by creating a temporary associative array, _arr
, whose indices are derived from the values of the input array. (Note that associative arrays are available in bash 4 and above, so this function won't work in earlier versions of bash.) We set $IFS
to avoid word splitting on whitespace.
The function contains no explicit loops, though internally bash steps through the input array in order to populate printf
. The printf format uses %q
to ensure that input data are escaped such that they can safely be used as array keys.
$ a=("one two" three four)
$ array_contains a three && echo BOOYA
BOOYA
$ array_contains a two && echo FAIL
$
Note that everything this function uses is a built-in to bash, so there are no external pipes dragging you down, even in the command expansion.
And if you don't like using eval
... well, you're free to use another approach. :-)