Como posso verificar se uma matriz zsh contém um determinado valor?

5

Suponha que eu tenha uma matriz não-associativa que tenha sido definida como

my_array=(foo bar baz)

Como posso verificar se a matriz contém uma determinada string? Eu preferiria uma solução que pudesse ser usada na condição de um bloco if (por exemplo, if contains($my_array, "something"); then ... ).

    
por bdesham 16.12.2017 / 20:48

2 respostas

6

Se você tiver uma matriz $my_array e quiser saber se ela contém a string foo , o teste é

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

O valor exato e completo do elemento da matriz deve ser foo ; não é uma verificação de substring ou algo assim.

Se você quiser ver se o valor da variável $my_string está na matriz, use

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

Esta sintaxe (ie) não é muito óbvia. É explicado na seção Subscript Flags do manual do ZSH. A parte i significa que estamos usando “subscrição inversa”: em vez de passar um índice e obter um valor, como fazemos com o usual ${my_array[1]} , estamos passando um valor e pedindo o primeiro subscrito que seria dê esse valor. Este subscrito é numérico e baseado em 1 (o primeiro elemento da matriz está no índice 1), que é diferente da convenção usada pela maioria das linguagens de programação. O e em (ie) significa que queremos uma correspondência exata, sem expandir os caracteres de correspondência de padrão, como * .

Se o valor não for encontrado na matriz, ${my_array[(ie)foo] será avaliado para o primeiro índice após o final da matriz, portanto, para uma matriz de 3 elementos, ele retornará 4. ${#my_array} fornece o índice do último elemento da matriz, portanto, se o primeiro for menor ou igual a último, o valor fornecido estará presente na matriz em algum lugar. Se você quiser verificar se um dado valor é não na matriz, altere o valor "menor que ou igual a" para "maior que":

[[ ${my_array[(ie)foo]} -gt ${#my_array} ]]
    
por 16.12.2017 / 21:15
5
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]} retorna o índice da última ocorrência de foo em $array e 0, se não encontrado. O sinal e é para que seja uma correspondência e xact em vez de uma correspondência de padrões.

Para saber quantas vezes o valor é encontrado na matriz, você pode usar o operador ${A:*B} (elementos da matriz A que também estão na matriz B ):

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

Tags