Cette réponse est spécifique au cas de la suppression de plusieurs valeurs dans de grands tableaux, où les performances sont importantes.
Les solutions les plus votées sont (1) la substitution de motifs sur un tableau, ou (2) l'itération sur les éléments du tableau. La première est rapide, mais ne peut traiter que les éléments qui ont un préfixe distinct, la seconde a O(n*k), n=taille du tableau, k=éléments à supprimer. Les tableaux associatifs sont une fonctionnalité relativement nouvelle, qui n'était peut-être pas courante lorsque la question a été posée à l'origine.
Pour le cas de la correspondance exacte, avec de grands n et k, il est possible d'améliorer les performances de O(n k) à O(n+k log(k)). En pratique, O(n) suppose que k est beaucoup plus petit que n. La plupart de l'accélération est basée sur l'utilisation de tableaux associatifs pour identifier les éléments à supprimer.
Performance (taille du tableau n, k-valeurs à supprimer). Mesure de la performance secondes de temps d'utilisation
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, le current
est linéaire par rapport à N*K, et la solution de fast
est pratiquement linéaire par rapport à K, avec une constante beaucoup plus faible. Le site fast
est légèrement plus lente que la solution current
solution lorsque k=1, en raison de la 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[@]}")
Comparaison avec current
solution, à partir de 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[@]}")