Язык программирования Perl
Шрифт:
В скалярном контексте функция values возвращает количество значений в хэше, так что ее можно использовать для того, чтобы узнать размер хэша. Например:
Функция each является встроенным итератором - программной конструкцией, контролирующей последовательную обработку элементов какой-либо коллекции данных. Она предоставляет возможность последовательно обработать все ассоциативные пары в хэше, организуя перебор всех его элементов.
После того как будет возвращена последняя пара элементов хэша, функция each возвращает пустой список. После этого следующий вызов each начнет перебор элементов хэша сначала. С ее помощью удобно организовать обработку всех элементов хэша в цикле, который закончится, когда each вернет пустой список, означающий "ложь":
Иногда требуется искать ключи хэша по их значениям. Для этого нужно создать обратный ассоциативный массив (или инвертированный хэш), поменяв местами значения и ключи хэша. Это можно сделать так:
Этого же результата можно достичь с помощью функции reverse, воспользовавшись тем, что она воспринимает хэш как список, в котором за каждым ключом идет значение, и меняет порядок всех элементов этого списка на обратный. Функция reverse возвращает список, в котором в каждой паре элементов за значением следует ключ, и этот список присваивается новому хэшу:
Нечетные элементы инвертированного списка становятся ключами, а четные - значениями хэша %hash_by_value.
Так как весь хэш, его ключи или значения можно легко преобразовать в список, то для обработки хэшей можно применять любые функции, работающие со списками. Именно поэтому в предыдущем примере была применена функция reverse. Например, вывести ключи и значения хэша на печать можно так:
Можно напечатать хэш по-другому, построчно и в более облагороженном виде, при помощи функции map, которая также выполняет роль итератора:
В этом примере на основании списка ключей, возвращенного функцией keys, функция map формирует список нужных строк, вставляя из хэша в каждую из них ключ и значение. Она возвращает сформированный список функции print, которая выводит его в выходной поток. Кстати, это типичный для Perl прием - обрабатывать данные при помощи цепочки функций, когда результат работы одной функции передается на обработку другой, как это принято делать с помощью конвейеров команд в операционных системах семейства Unix.
В приведенных выше примерах при необходимости обработки ключей хэша в алфавитном порядке они сортировались с помощью функции sort. Вот пример обработки хэша в порядке возрастания не его ключей, а его значений:
Здесь в блоке сравнения функции sort сопоставляется значения хэша, ассоциированные с очередными двумя ключами из списка, который предоставлен функцией keys.
Подобно тому, как при работе с массивами срезы позволяют работать со списком элементов, в Perl есть возможность обращаться сразу с несколькими элементами хэша. Это делается с помощью среза хэша. Срез хэша (hash slice) - это список значений хэша, заданный перечнем соответствующих ключей. Он записывается в виде имени хэша с префиксом @ (так как срез - это список), за которым в фигурных скобках перечисляются ключи. Список ключей в срезе хэша можно задать перечислением скалярных значений, переменной-списком или списком, возвращенным функцией. Например, так:
Если в срезе хэша список ключей состоит из единственного ключа, срез все равно является списком, хотя и из одного значения. Сравните:
Поскольку переменная-хэш в составе строки не интерполируется, для вставки в строку всех значений хэша можно воспользоваться срезом хэша:
Срез хэша, как и любой другой список, может стоять в левой части операции присваивания. При этом списку ключей среза должен соответствовать список присваиваемых значений в правой части присваивания. Воспользовавшись срезом, можно добавить в хэш сразу несколько пар или объединить два хэша, добавив к одному другой. Например: