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


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


Применение foreach и keys для перебора списка позволяет установить свой порядок обработки Предположим, нам понадобилось вывести содержимое хэша в алфавитном порядке ключей:

foreach $food (sort keys %food_color) { print $food is $food_color{$food} \n


5.4. Перебор хэша   159

Apple is red. Banana   is   yellow. Carrot   is   orange. Lemon   is   yellow.

Подобное применение f о reach встречается довольно часто. Функция keys стро­ит список ключей в хэше, после чего foreach перебирает их. Если хэш состоит из большого числа элементов, возникает опасность, что возвращаемый keys список займет много памяти. Приходится выбирать между затратами памяти и возмож­ностью обработки элементов в определенном порядке. Сортировка подробнее рас­сматривается в рецепте 5.9.

Поскольку функции keys, values и each используют одни и те же внутрен­ние структуры данных, следует внимательно следить за чередованием вызовов этих функций или преждевременным выходом из цикла each. При каждом вызо­ве keys или values текущая позиция each сбрасывается. Следующий фрагмент за­цикливается и бесконечно выводит первый ключ, возвращаемый each:

while (  ($k,$v) = each %food_color) {

print    Processing $k\n ,

keys %food_color,                    # Возврат к началу %food_color

}

Модификация хэша во время его перебора в each или foreach, как правило, со­пряжена с опасностью. При добавлении или удалении ключей из хэша функция each ведет себя по-разному для связанных и несвязанных хэшей. Цикл foreach пере­бирает заранее построенный список ключей, поэтому после начала цикла он ни­чего не знает о добавленных или удаленных ключах. Ключи, добавленные внутри цикла, не включаются автоматически в список перебираемых ключей, а удален­ные внутри цикла ключи не удаляются из этого списка.

Программа countfrom из примера 5.1 читает файл почтового ящика и выводит количество сообщений от каждого отправителя. Отправитель определяется по строке From: (в этом отношении сценарий не очень интеллектуален, однако нас сейчас интересуют операции с хэшами, а не обработка почтовых файлов). Пере­дайте имя почтового ящика в командной строке или используйте - для пере­направления.




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