Esta respuesta es específica para el caso de eliminar varios valores de matrices grandes, donde el rendimiento es importante.
Las soluciones más votadas son (1) sustitución de patrones en una matriz, o (2) iterar sobre los elementos de la matriz. El primero es rápido, pero solo puede tratar con elementos que tienen un prefijo distinto, el segundo tiene O (n * k), n = tamaño de matriz, k = elementos para eliminar. La matriz asociativa es una característica relativamente nueva y es posible que no haya sido común cuando se publicó originalmente la pregunta.
Para el caso de coincidencia exacta, con n y k grandes, es posible mejorar el rendimiento de O (n k) a O (n + k log (k)). En la práctica, O (n) asumiendo k mucho menor que n. La mayor parte de la aceleración se basa en el uso de una matriz asociativa para identificar los elementos que se eliminarán.
Rendimiento (tamaño de matriz n, valores k para eliminar). Segundos de medición del rendimiento del tiempo del usuario
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 era de esperar, la current
solución es lineal a N * K, y la fast
solución es prácticamente lineal a K, con una constante mucho más baja. La fast
solución es un poco más lenta que la current
solución cuando k = 1, debido a una configuración adicional.
La solución 'Rápida': matriz = lista de entrada, eliminar = lista de valores para eliminar.
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 con la current
solución, a partir de la respuesta más 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
.