PERL: БИБЛИОТЕКА ПРОГРАММИСТА - стр. 126
Прямолинейно
%seen = (), @uniq = ()
foreach Sitpm (@list) { unless ($seen{$item})
# Если мы попали сюда, значит, элемент не встречался ранее
$seen{$item} = 1
push(@umq $item),
Быстро
%seen = (),
foreach $item (ia>list) {
push((g>uniq Sitem) unless $seen{$item}++,
126 Глава 4 • Массивы
Аналогично, но с пользовательской функцией
%seen =(),
foreach $item (@list) {
some_func($item) unless $seen{$item}++ }
Быстро, но по-другому
%seen = (),
foreach $item (@list) { $seen{$item}++,
V /
@uniq = keys %seen,
Быстро и совсем по-другому
%seen = (),
©unique = grep { ' $seen{$_} ++ } @list,
Комментарий
Суть сводится к простому вопросу — встречался ли данный элемент раньше? %эпш идеально подходят для подобного поиска. В первом варианте («Прямолинейно») массив уникальных значений строится но мере обработки исходного списка, а для регистрации встречавшихся значений используется хэш.
Второй вариант («Быстро») представляет собой самый естественный способ решения подобных задач в Perl. Каждый раз, когда встречается новое значение, в хэш с помощью оператора ++ добавляется новый элемент. Побочный эффект состоит в том, что в хэш попадают ж e повторяющиеся экземпляры. В данном случае хэш работает как множество.
Третий вариант («Аналогично, но с пользовательской функцией») похож на второй, однако вместо сохранения значения мы вызываем некоторую пользовательскую функцию и передаем ей это значение в качестве аргумента. Если ничего больше не требуется, хранить отдельный массив уникальных значений будет излишне.
В следующем варианте («Быстро, по по-другому») уникальные ключи извлекаются из хэша %seen лишь после того, как он будет полностью построен. Иногда это удобно, но исходный порядок элементов утрачивается.
В последнем варианте («Быстро и совсем по-другому») построение хэша %seen объединяется с извлечением уникальных элементов. При этом сохраняется исходный порядок элементов.
Использование хэша для записи значений имеет два побочных эффекта: при обработке длинных списков расходуется много памяти, а список, возвращаемый keys, не отсортирован в алфавитном или числовом порядке и не сохраняет порядок вставки.
