Для того чтобы организовать циклы
Для того чтобы организовать циклы по элементам хэша, нужно использовать функцию each:
%hash = (
'шляпа' => 'серая',
'водка' => 'горькая',
'вобла' => 'вкусная');
while(($key,$value) = each %hash){
print "$key => $value\n";
};
Для перебора элементов не очень большого хеша можно воспользоваться foreach:
%hash = (
'шляпа' => 'серая',
'водка' => 'горькая',
'вобла' => 'вкусная');
foreach $key(keys %hash){
print $key,"\n"; #возвращает список ключей хеша
}
%hash = (
'шляпа' => 'серая',
'водка' => 'горькая',
'вобла' => 'вкусная');
foreach $value(values %hash){
print "$value\n"; #возвращает список значений хеша
}
Преимущество each заключается в том, что пары ключ/значение извлекаются по одной, Если хэш содержит слишком много ключей, отказ от предварительного построения полного списка существенно экономит память и время, но функция each не позволяет управлять порядком обработки пар. Перебор хэша при помощи while затрачивает мало памяти. Можно любым образом форматировать выходные данные, при этом нужны всего лишь две скалярные переменные, ключ и значение.
Цикл foreach перебирает заранее построенный список ключей, поэтому после начала цикла он ничего не знает о добавленных или удаленных ключах, ключи, добавляемые внутри цикла, не включаются автоматически в список перебираемых ключей, а удаленные внутри цикла ключи не удаляются из этого списка.
Содержимое хэша можно вывести и так:
while (@Res = each %hash){
print "$Res[0] = $Res[1]\n"
}
Вывод хэша одной строкой.
можно воспользоваться функцией map:
print map {"$_ => $hash{$_}\n"} keys %hash;
функция map позволяет работать с элементами в произвольном порядке, в этом случае создается список строк(ключ => значение), передаваемый функции print. Если сохранить хэш во временном массиве, то он будет выведен как строка:
{
my @temp = %hash;
print "@temp";
}
также можно вывести хэш и таким образом:
print "@{[%hash]}\n";
в двух последних случаях мы интерполируем хэш как список, что не позволяет предсказать или управлять порядком вывода пар "ключ/значение". Данные в последних двух случаях выводятся в виде списка ключей и значений, элементы которого разделяются текущим содержимым переменной $", т.е. не удастся вывести каждую пару значений на новой строке или отделить ключи от значений каким-либо символом. Приведем программу, которая читает файл почтового ящика и выводит количество сообщений от каждого отправителя, отправитель определяется по строке From(цель программы только проиллюстрировать операции с хешами):
#!/usr/bin/perl -w
$file = $ARGV[0] "-";
open(FILE, "
Запускаем программу чтения почтового ящика: bash-2.03$ ./1.pl /usr/home/vovka/mbox
Инвертирование хэша производится при помощи функции reverse, в котором ассоциированные значения исходного хэша являются ключами и наоборот. Воспользуемся списковой эквивалентностью хэшей. В списковом контексте reverse иетерпретирует %hash как список и меняет местами составляющие его элементов. Например: имеем хэш %Glavfish = ("seledka"=>"mokraia","skat"=>"elektricheskij"), если его интерпретировать как список, то получим следующее ("seledka","mokraia","skat","elektricheskij"), после инвертирования список выглядит так: ("elektricheskij","skat","mokraia","seledka"), интерпретация его как хэша дает следующее: ("elektricheskij"=>"skat","mokraia"=>"seledka").