Используйте сплайс, если вы уже знаете индекс элемента, который хотите удалить.
Grep работает, если вы ищете.
Если вам понадобится выполнить много таких действий, вы получите гораздо лучшую производительность, если будете держать свой массив в отсортированном порядке, поскольку затем вы можете выполнить бинарный поиск, чтобы найти необходимый индекс.
Если это имеет смысл в вашем контексте, вы можете рассмотреть возможность использования «магического значения» для удаленных записей, а не их удаления, чтобы сэкономить на перемещении данных - например, установите для удаленных элементов значение undef. Естественно, у этого есть свои проблемы (если вам нужно знать количество «живых» элементов, вам нужно отслеживать их отдельно и т. Д.), Но это может стоить проблем в зависимости от вашего приложения.
Редактировать Собственно, теперь, когда я перехожу на второй взгляд - не используйте приведенный выше код grep. Было бы более эффективно найти индекс элемента, который вы хотите удалить, а затем использовать сплайс для его удаления (у вас есть код, который накапливает все несоответствующие результаты ..)
my $index = 0;
$index++ until $arr[$index] eq 'foo';
splice(@arr, $index, 1);
Это удалит первое вхождение.
Удаление всех вхождений очень похоже, за исключением того, что вы хотите получить все индексы за один проход:
my @del_indexes = grep { $arr[$_] eq 'foo' } 0..$#arr;
Остальное оставлено в качестве упражнения для читателя - помните, что массив изменяется по мере его соединения!
Edit2 Джон Сиракуза правильно указал, что в моем примере была ошибка ... исправлена, извините за это.