Анимация
JavaScript


Главная  Библионтека 

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 [ 32 ] 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122

что ваш результат может отличаться от приведенного в книге порядком следования элементов, поскольку функция keys возвращает ключи в неупорядоченном виде.

Кроме keys, в Perl есть также функция values, предназначенная для доступа к значениям всех элементов хэша. Извлечение значений отдельно от ключей не позволяет узнать, с каким ключом связано каждое конкретное значение. Функция values возвращает значения хэша в том же порядке, что и keys возвращает ключи. Вот пример:

eDirectors=values %Hovies; eFilBs=keys *Movies;

Здесь элементы и с одинаковым индексом образуют пару ключ-

значение хэшаfcMovies. Имя режиссера в $Directors(0] соответствует названию фильма SFilms[0] и т.д.

Часто нужно извлечь индивидуальный элемент хэша не по ключу, а по его значению. Для этого существует специальный метод доступа, называемый инверсией хэша. Он заключается в том, что ключи и значения меняются местами, т.е. все ключи становятся значениями, а все значения становятся ключами:

»HovieB= ( e Shining => Kubrick, •Ten Commandments => DeMille,

Goonies => Spielberg); %ByDirector=reverse IMovies;

Как этот код работает? Функция reverse рассматривает хэш как обычный список:

( The Shining, Kubrick, Tten Camandnents, DeMille, Goonies, Spielberg )

Затем порядок следования элементов этого списка изменяется на обратный, в результате чего получается следующий список:

( Spielberg, Goonies,

Delle , Ten Cotangents, Kubrick, The Shining )

Обратите внимание, что внутри пар ключ-значение произошли перестановки - значения теперь находятся впереди. После присвоения получившегося списка хэшу IByDirector мы получаем хэш, практически идентичный исходному, за исключением того, что значения исходного хэша стали ключами нового, а ключи исходного - значениями нового. Будьте осторожны с подобной операцией, если некоторые элементы исходного хэша имеют одинаковые значения. Если значения, которые становятся ключами, не уникальны, в новом хэше будет меньшее количество элементов, чем в исходном. Как только в новом хэше будет встречаться уже имеющееся значение, старый ключ будет заменяться новым.

Списки и хэши

При обсуждении вопроса инициализации хэша отмечалась близкая связь хэшей и массивов. Когда хэш используется в контексте списка, Perl воспринимает его в виде обычного списка ключей и значений. Этот список может быть присвоен массиву, как и любой другой список:

*Movies= ( Th ing => Kubric,

Ten Cotangents => lle,

GcxDnies => Spielberg) ;

SData=%Movies;



После выполнения этого кода массив будет содержать шесть элементов.

Причем элементы с четными индексами (включая нуль) соответствуют именам режиссеров, а элементы с нечетными индексами - названию фильмов. С этим массивом можно выполнить любую операцию, возможную с массивами, и затем присвоить получившийся массив хэшу %Movies:

tMovies=edata;


Perl хранит элементы хэша в удобном для обработки порядке, который с точки зрения пользователя является случайным. Последовательность ввода ключей хэша не запоминается и выводятся они в произвольном порядке. Для упорядоченного вывода элементов хэша нужно или отсортировать их (см. ниже раздел "Практическое применение хэшей"), или запомнить порядок, в котором вводились ключи (см. раздел "Вопросы и ответы" в конце этого занятия).

Массивы и хэши имеют сходства и в другом. Для копирования хэша достаточно присвоить один хэш другому:

tNew Hash=%Old Hashj

Когда вы помещаете Hash в правую часть оператора присваивания, там, где обычно Perl ожидает встретить список или массив, преобразует хэш в список, используемый в дальнейшем для инициализации %New Hash. Подобным образом вы можете комбинировать хэши и манипулировать ими, как списками:

tBoth=(tFlrEt, %Second);

IAdditional=(*Both, keyl = , кеу2 => value2)!

Первый снисок объединяет два хэша, %First и ISecond в третий хэш IBoth. Если некоторые ключи % First нрисутствуют в * Second, пара ключ-значение второго хэша заменяет пару ключ-значение первого. Во второй строке *Both представлен списком пар ключ-значение. Кроме него в скобках есть еще две пары ключ-значение. Полученный полный список используется для инициализации хэша

Дополнительная информация о хэшах

ЕСЛИ ВЫ НОВИЧОК В Perl, некоторые операции с хэшами будут для вас далеко не очевидны. Из-за специфической природы хэшей для некоторых часто встречающихся

операций понадобятся новые функции, в которых не было необходимости при работе

со скалярами и массивами.

Проверка ключей хэша

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

if eyval} ) { t гст крд 1пра<ЛЕ1ьй )

Этот пример не будет работать, поскольку в нем нет проверки, действительно ли является ключом хэша, вместо этого проверяется значение, соответствующее ключу keyval. А если написать так:

if { rlireH аууяТ} ) { i СПСЭТЬ НЗраЮЫЗЬЙ КСЩ J

114 Часть!. Основы Peri



и это не совсем то, что нужно. В нем проверяется существование данных, связанных с ключом keyval, а не самого ключа. А ведь вполне допускается связывать с ключом хэша значение undef:

$SaEh{ key val} =uudef;

Проверка данного элемента выдаст ложное значение, потому что проверяется не наличие ключа, а связанное с ним значение. Итак, как же сделать проверку ключей корректно? Для этого в Perl есть специальная функция exists. Функция exists проверяет наличие указанного ключа в хэше и возврашает либо истинное значение (если

ключ существует), либо ложное (в противном случае):

if { exists keyval} ) { if Теперь правильно! >

Удаление ключей из хэша

Другая неочевидная операция - удаление ключей из хэша. Как вы уже убедились, присвоение элементу хэша значения undef здесь не сработает. Для удаления одного ключа хэша можно воспользоваться функцией delete: delete $Haeh{keyval};

Для удаления всех ключей и значений из хэша можно просто инициализировать хэш пустым списком:

tfiashO;

Практическое применение хэшей

Хэши часто используются Perl не только для хранения записей, доступ к которым выполняется по значению ключей. Основные преимущества хэшей - быстрый доступ к отдельному ключу и уникальность ключей. Эти особенности неоценимы при

обработке данных. Из-за сходства с массивами хэши будут особенно полезны для преобразования массивов данных.

Определение частоты появления слов

На 6-м занятии, "Поиск по шаблону", вы узнали, как разделить строку текста на

отдельные слова. Посмотрите на следующий фрагмент кода:

whileCO) {

viiUfi ( /{\w[\w-]*)/g ) { t Итерация по Boai огжам с innipo тщ&ввесй

, $Words{Sl}++;

Проведем анализ этого кода. В первой строке выполняется чтение информа-иии со стандартного устройства ввода. При этом введенные значения поочередно присваиваются переменной $ . Следующий цикл while совершает итерацию по всем словам, находящимся в переменной Из 6-го занятия, "Поиск по шаблону", вы должны помнить, что оператор поиска по шаблону ( ) в скалярном контексте и с модификатором g возвращает истинное значение до тех пор, пока не буд найдены все совпадения с шаблоном. Шаблон состоит из



0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 [ 32 ] 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122