Cette réponse est spécifique au cas de la suppression de plusieurs valeurs de grands tableaux, où les performances sont importantes.
Les solutions les plus votées sont (1) la substitution de motif sur un tableau, ou (2) l'itération sur les éléments du tableau. Le premier est rapide, mais ne peut traiter que des éléments qui ont un préfixe distinct, le second a O (n * k), n = taille du tableau, k = éléments à supprimer. Les tableaux associatifs sont une nouvelle fonctionnalité relative et peuvent ne pas avoir été courants lorsque la question a été initialement publiée.
Pour le cas de correspondance exacte, avec n et k grands, il est possible d'améliorer les performances de O (n k) à O (n + k log (k)). En pratique, O (n) en supposant que k bien inférieur à n. La plupart de l'accélération repose sur l'utilisation d'un tableau associatif pour identifier les éléments à supprimer.
Performances (taille n-array, valeurs k à supprimer). Mesure des performances en secondes de temps utilisateur
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%
Comme prévu, la current
solution est linéaire à N * K, et la fast
solution est pratiquement linéaire à K, avec une constante beaucoup plus faible. La fast
solution est légèrement plus lente que la current
solution lorsque k = 1, en raison d'une configuration supplémentaire.
La solution 'Rapide': array = liste des entrées, delete = liste des valeurs à supprimer.
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[@]}")
Comparé à la current
solution, d'après la réponse la plus votée.
for target in "${delete[@]}"; do
for i in "${!array[@]}"; do
if [[ ${array[i]} = $target ]]; then
unset 'array[i]'
fi
done
done
array=("${array[@]}")
zsh
.