Ця відповідь характерна для випадку видалення кількох значень з великих масивів, де важлива продуктивність.
Найбільш голосовими рішеннями є (1) підміна шаблону на масиві або (2) ітерація над елементами масиву. Перший швидко, але може мати справу лише з елементами, які мають чіткий префікс, другий має O (n * k), n = розмір масиву, k = елементи для видалення. Асоціативний масив є відносно новою ознакою, і він, можливо, не був поширеним, коли питання було розміщено спочатку.
Для точного випадку відповідності, з великими n і k, можна підвищити продуктивність від O (n k) до O (n + k log (k)). На практиці O (n) припускаючи k набагато нижче n. Більшість прискорень базується на використанні асоціативного масиву для ідентифікації елементів, які потрібно видалити.
Продуктивність (розмір n-масиву, k-значення для видалення). Вимірювання продуктивності секунди часу користувача
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%
Як і очікувалося, current
розчин лінійний до N * K, а fast
розчин практично лінійний до K, зі значно меншою постійною. fast
Розчин трохи повільніше по порівнянні з current
рішенням , коли до = 1, з - за додаткового налаштування.
Рішення "Швидкий": array = список вводу, delete = список значень, які потрібно видалити.
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[@]}")
Орієнтований проти current
рішення, з найбільш голосової відповіді.
for target in "${delete[@]}"; do
for i in "${!array[@]}"; do
if [[ ${array[i]} = $target ]]; then
unset 'array[i]'
fi
done
done
array=("${array[@]}")
zsh
.