Ta odpowiedź jest specyficzna dla przypadku usuwania wielu wartości z dużych tablic, w których ważna jest wydajność.
Najczęściej głosowanymi rozwiązaniami są (1) podstawianie wzorców w tablicy lub (2) iterowanie po elementach tablicy. Pierwsza jest szybka, ale może obsługiwać tylko elementy, które mają odrębny prefiks, druga ma O (n * k), n = rozmiar tablicy, k = elementy do usunięcia. Tablica asocjacyjna jest stosunkowo nową funkcją i mogła nie być powszechna, gdy pytanie zostało pierwotnie opublikowane.
Dla przypadku dokładnego dopasowania, z dużymi n i k, możliwe jest zwiększenie wydajności od O (n k) do O (n + k log (k)). W praktyce O (n) zakładając, że k jest znacznie mniejsze niż n. Większość przyspieszenia opiera się na wykorzystaniu tablicy asocjacyjnej do identyfikacji elementów do usunięcia.
Wydajność (rozmiar n-tablicy, wartości k do usunięcia). Wydajność mierzy sekundy czasu użytkownika
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%
Zgodnie z oczekiwaniami, current
rozwiązanie jest liniowe do N * K, a fast
rozwiązanie jest praktycznie liniowe do K, ze znacznie niższą stałą. fast
Rozwiązanie jest nieco wolniejsza vs current
roztworu gdy k = 1, ze względu na dodatkową konfigurację.
Rozwiązanie „Szybkie”: tablica = lista danych wejściowych, usuń = lista wartości do usunięcia.
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[@]}")
Porównanie z current
rozwiązaniem, na podstawie najczęściej głosowanej odpowiedzi.
for target in "${delete[@]}"; do
for i in "${!array[@]}"; do
if [[ ${array[i]} = $target ]]; then
unset 'array[i]'
fi
done
done
array=("${array[@]}")
zsh
.