PERL: БИБЛИОТЕКА ПРОГРАММИСТА


PERL: БИБЛИОТЕКА ПРОГРАММИСТА - стр. 139


Давайте рассмотрим реальный пример сортировки. Мы собираем информа­цию обо всех пользователям в виде объектов User pwent, после чего сортируем их по именам и выводим отсортированный список:

use User    pwent qw(getpwent), ©users = (),

# Выбрать всех пользователей while (aefined($user = getpwent))  { push(@users,   $user),


4.15. Сортировка списка по вычисляемому полю   141

gusers = sort  {  $a->name cmp $b-<name } ©users, foreach $user (©users)   {

print $user->name,    \n , }

Возможности не ограничиваются простыми сравнениями или комбинациями простых сравнений. В следующем примере список имен сортируется по второй букве имени. Вторая буква извлекается функцией substr:

©sorted = sort  {  substr($a 1,1)  cmp substr($b,1  1)   } @names, А ниже список сортируется по длине строки:

©sorted = sort  {  length $a <=> length $b } ©strings,

Функция сравнения вызывается sort каждый раз, когда требуется сравнить два элемента. Число сравнений заметно увеличивается с количеством сортируе­мых элементов. Сортировка 10 элементов требует (в среднем) 46 сравнений, од­нако при сортировке 1000 элементов выполняется 14 000 сравнений. Медленные операции (например, split или вызов подпрограммы) при каждом сравнении тор­мозят работу программы.

К счастью, проблема решается однократным выполнением операции для каж­дого элемента перед сортировкой. Воспользуйтесь тар для сохранения результатов операции в массиве, элементы которого являются анонимными массивами с ис­ходным и вычисленным полем. Этот «массив массивов» сортируется по пред­варительно вычисленному полю, после чего тар используется для получения от­сортированных исходных данных. Концепция map/sort/map применяется часто и с пользой, поэтому ее стоит рассмотреть более подробно.

Применим ее к примеру с сортировкой по длине строки:

©temp = map { [ length $_, $_ ] } ©strings, ©temp = sort { $a->[0] <=> $b->[0] } @temp, ©sorted = map { $_->[1] } ©temp,

В первой строке map создает временный массив строк с их длинами. Вторая строка сортирует временный массив, сравнивая их предварительно вычисленные длины. Третья строка превращает временный массив строк/длин в отсортированный массив строк. Таким образом, длина каждой строки вычисляется всего один раз.




- Начало -  - Назад -  - Вперед -