Questa risposta è specifica per l'eliminazione di più valori da array di grandi dimensioni, in cui le prestazioni sono importanti.
Le soluzioni più votate sono (1) la sostituzione di pattern su un array o (2) l'iterazione sugli elementi dell'array. Il primo è veloce, ma può trattare solo elementi che hanno prefissi distinti, il secondo ha O (n * k), n = dimensione dell'array, k = elementi da rimuovere. Gli array associativi sono una nuova funzionalità relativa e potrebbero non essere comuni quando la domanda è stata originariamente pubblicata.
Per il caso di corrispondenza esatta, con n e k grandi, è possibile migliorare le prestazioni da O (n k) a O (n + k log (k)). In pratica, O (n) assumendo k molto inferiore a n. La maggior parte della velocità si basa sull'utilizzo di array associativi per identificare gli elementi da rimuovere.
Prestazioni (dimensione n-array, valori k da eliminare). Le prestazioni misurano i secondi del tempo dell'utente
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%
Come previsto, la current
soluzione è lineare per N * K e la fast
soluzione è praticamente lineare per K, con una costante molto più bassa. La fast
soluzione è leggermente più lenta rispetto alla current
soluzione quando k = 1, a causa della configurazione aggiuntiva.
La soluzione "veloce": array = elenco di input, delete = elenco di valori da rimuovere.
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[@]}")
Benchmark rispetto alla current
soluzione, dalla risposta più votata.
for target in "${delete[@]}"; do
for i in "${!array[@]}"; do
if [[ ${array[i]} = $target ]]; then
unset 'array[i]'
fi
done
done
array=("${array[@]}")
zsh
.