Essa resposta é específica para o caso de exclusão de vários valores de grandes arrays, onde o desempenho é importante.
As soluções mais votadas são (1) substituição de padrão em uma matriz ou (2) iteração sobre os elementos da matriz. O primeiro é rápido, mas só pode lidar com elementos que têm prefixo distinto, o segundo tem O (n * k), n = tamanho do array, k = elementos para remover. Matrizes associativas são recursos relativamente novos e podem não ter sido comuns quando a pergunta foi postada originalmente.
Para o caso de correspondência exata, com n e k grandes, é possível melhorar o desempenho de O (n k) para O (n + k log (k)). Na prática, O (n) assumindo k muito menor que n. A maior parte da aceleração é baseada no uso de matriz associativa para identificar os itens a serem removidos.
Desempenho (tamanho da matriz n, valores k a serem excluídos). Mede o desempenho em segundos de tempo do usuário
N K New(seconds) Current(seconds) Speedup
1000 10 0.005 0.033 6X
10000 10 0.070 0.348 5X
10000 20 0.070 0.656 9X
10000 1 0.043 0.050 -7%
Como esperado, a current
solução é linear para N * K, e a fast
solução é praticamente linear para K, com constante muito menor. A fast
solução é ligeiramente mais lenta em relação aocurrent
solução quando k = 1, devido à configuração adicional.
A solução 'Rápida': array = lista de entrada, delete = lista de valores a serem removidos.
declare -A delk
for del in "${delete[@]}" ; do delk[$del]=1 ; done
# Tag items to remove, based on
for k in "${!array[@]}" ; do
[ "${delk[${array[$k]}]-}" ] && unset 'array[k]'
done
# Compaction
array=("${array[@]}")
Comparado com a current
solução, a partir da resposta mais votada.
for target in "${delete[@]}"; do
for i in "${!array[@]}"; do
if [[ ${array[i]} = $target ]]; then
unset 'array[i]'
fi
done
done
array=("${array[@]}")
zsh
.