Работа с массивами и хэшами.
Различают два типа массивов: индексные, у которых в качестве индекса только целое число, и ассоциативные, где индексом может быть любой объект.
Индексные массивы чаще всего называют просто «массивами», а ассоциативные массивы - «хешами» или «словарями».
Хеши можно представить как массив пар: ключ=>значение. Но в отличие от массива, хеш неупорядочен: нельзя заранее сказать, какая пара будет первой, а какая последней. Правда, удобство использования массива это не уменьшает. Более того, поскольку в Ruby переменные не типизированы и методам с похожей функциональностью дают похожие имена, то использование хеша чаще всего равносильно использованию массива.
Хэш - ассоциативный массив, т.к. доступ к данным осуществляется при помощи ключа, ассоциированного со значением. Хэши начинаются с префикса %: %hash. Для работы с хэш-массивами нужно, как и в обычных массивах, использовать разыменовывающий префикс $: $hash{шляпа} = серая;
Хэш можно определить несколькими способами:
%hash = ( 'шляпа' => 'серая',
'игрушка' => 'любимая');
Но, при этом %hash = (); #можно не указывать пустой хеш для создания массива, perl может сам создавать пустой хэш.
Если используется пробел при определении элемента хэша, то этот пробел лучше поставить в одинарные кавычки $hash{'дырявая шляпа'} = серая;
При работе с хэшом можно:
· добавить элементы в хеш
· осуществить проверку хэша на наличие каких-либо элементов.
· удалить какой-либо элемент ( это можно сделать при помощи функции delete. Функция delete может вызываться для среза хэша, что приводит к удалению всех указанных ключей: delete @hash{'шляпа','штаны','игрушка'}; )
Для того чтобы организовать циклы по элементам хэша, нужно использовать функцию each. Также для перебора элементов не очень большого хеша можно воспользоваться foreach.
Преимущество each заключается в том, что пары ключ/значение извлекаются по одной. И при этом, если хэш содержит слишком много ключей, отказ от предварительного построения полного списка существенно экономит память и время, но функция each не позволяет управлять порядком обработки пар.
Перебор хэша при помощи while затрачивает мало памяти. Можно любым образом форматировать выходные данные, при этом нужны всего лишь две скалярные переменные, ключ и значение.
Цикл foreach перебирает заранее построенный список ключей, поэтому после начала цикла он ничего не знает о добавленных или удаленных ключах, ключи, добавляемые внутри цикла, не включаются автоматически в список перебираемых ключей, а удаленные внутри цикла ключи не удаляются из этого списка.
При выводе хэша одной строкой можно воспользоваться функцией map: print map {"$_ => $hash{$_}\n"} keys %hash; функция map позволяет работать с элементами в произвольном порядке, в этом случае создается список строк (ключ => значение), передаваемый функции print. Если сохранить хэш во временном массиве, то он будет выведен как строка, также можно вывести хэш и таким образом: print "@{[%hash]}\n"; . В двух последних случаях хэш рассматривается как список, что не позволяет предсказать или управлять порядком вывода пар "ключ/значение". Данные в последних двух случаях выводятся в виде списка ключей и значений, элементы которого разделяются текущим содержимым переменной $", т.е. не удастся вывести каждую пару значений на новой строке или отделить ключи от значений каким-либо символом.
Хэши с несколькими значениями, ассоциированными одним ключом. Операции с хэшами (вставка, удаление, перебор и проверка существования(undef)) переписываются для операций с массивами(push, splice и foreach).
Инвертирование хэша производится при помощи функции reverse, в котором ассоциированные значения исходного хэша являются ключами и наоборот.
Сортировка хэша может быть:
· в алфавитном порядке по значениям ключа
· сортировка по значению
· сортировка ключей по алфавиту ассоциированных значений
· сортировка по длинне ассоциированных значений
Слияние хешей выполняется как и слияние массивов. Если нужно найти совпадающие ключи или не входящие в другй хэш, то надо организовать перебор ключей хэша при помощи keys и проверять, если ли текущий ключ в другом хэше. Если keys вызывается для хэша, ключи которого представляют собой ссылки, то возвращаемые ей ссылки не работают. Ключи преобразуются в строки, т.е. интерпретируются так, словно они заключены в кавычки, при работе со ссылками они теряют свои свойства.
Но важно помнить, что преобразованную ссылку нельзя вернуть к прежнему виду, т.к. она из ссылки превратилась в строку. Нужно создать специальный хэш, ключами которого являются ссылки, преобразованные в строки, и значениями - настоящие ссылки. Можно воспользоваться модулем Tie::RefHash. Если в качестве ключа использована неопределенная величина undef, то она преобразуется в пустую строку. undef является вполне допустимым значением в хэше.
Переменные окружения, использующие встроенные хэши и массивы %INC, %SIG, %ENV, %FORM{} :
· %INC содержит имена файлов, включаемых командами do и require. Ключ имя файла, значение путь до включаемого файла. Массив @INC содержит список дирректорий, которые просматривает perl для выполнения команд do, require или use.
· %SIG - хэш, в котором хранятся обработчики различных ситуаций, возникающих в perl. Например строка local $SIG{__WARN__} = sub{}; отключает предупреждающие сообщения.
· %ENV содержит значения переменных среды(окружения), заданных на момент запуска сценария(скрипта).
Ключами обычно бывают имена переменных среды (но их состав зависит от операционной системы), изменение этих значений вызовет изменение окружения для процессов потомков.
Несмотря на мощь хеша, использовать его не всегда целесообразно. Бывают задачи, решаемые с хешами легко и удобно, но таких задач мало. Чаще всего хватает использования массива. Но общее представление о классе задач для хеша просто необходимо.
Дата добавления: 2016-04-23; просмотров: 1008;