Oto moje zdanie na ten temat.
Wolałbym nie używać basha dla pętli, jeśli mogę tego uniknąć, ponieważ to wymaga czasu. Jeśli coś musi się zapętlić, niech to będzie coś napisanego w języku niższego poziomu niż skrypt powłoki.
function array_contains { # arrayname value
local -A _arr=()
local IFS=
eval _arr=( $(eval printf '[%q]="1"\ ' "\${$1[@]}") )
return $(( 1 - 0${_arr[$2]} ))
}
Działa to poprzez utworzenie tymczasowej tablicy asocjacyjnej, _arr
której indeksy pochodzą z wartości tablicy wejściowej. (Zauważ, że tablice asocjacyjne są dostępne w wersji bash 4 i nowszych, więc ta funkcja nie będzie działać we wcześniejszych wersjach bash.) Ustawiliśmy, $IFS
aby uniknąć podziału słów na białe znaki.
Funkcja nie zawiera wyraźnych pętli, chociaż wewnętrznie przebija się przez tablicę wejściową w celu zapełnienia printf
. Format printf używa %q
do zapewnienia, że dane wejściowe są ucieczkowe, dzięki czemu można je bezpiecznie wykorzystać jako klucze tablicy.
$ a=("one two" three four)
$ array_contains a three && echo BOOYA
BOOYA
$ array_contains a two && echo FAIL
$
Zauważ, że wszystko, czego używa ta funkcja, jest wbudowane w bash, więc nie ma żadnych zewnętrznych potoków ciągnących cię w dół, nawet w rozszerzeniu poleceń.
A jeśli nie lubisz używać eval
... cóż, możesz zastosować inne podejście. :-)