Срезы хешей.
Хеш представляет собой набор скалярных данных, отдельные элементы которого
выбираются по индексному значению. Индексные значения хеша - произвольные
скаляры (ключи).
Отдельные элементы хеша не стоят в каком-то определенном порядке. Порядок
хранения пар ключ-значение изменить нельзя.
Имя хеш переменной состоит из знака процента и буквы или нескольких.
Обращение к элементам хеша %test производится путем указания
$test{$key}, где $key - любое скалярное выражение.
Создание новых элементов хеша путем присваивания значения:
$test{"abc"} = "cba";
$test{12.7} = 21.7;
Оращение к элементам хеша:
print $test{"abc"};
$test{12.7} += 3; # разультат 24.7
При обращении к несуществующему элементу хеша возвращается значение
undef.
Фактически в Perl никакого литерального формата для хеша не предусмотрено,
поэтому он просто представляется в виде списка:
@test_list = %test; # @test = qw(abc cba 12.7 24.7);
%test1 = @test_list; # создать test1 как test
%test1 = %test; # ускоренный метод
%test2 = ("abc", "cba", "12.7", "24.7");
# создать %test2 как %test
# из литеральных представлений
Порядок пар ключ-значение в этом развернутом формате произвольный и
контролю не поддается.
Используя операцию reverse, можно создать хеш, в котором
ключи и значения поменяются местами:
%backwards = reverse %normal;
Если %normal имеет два идентичных значения, то в %backwards
они преватятся в один элемент.
Некоторые функции, предназначенные для обработки хешей.
Функция keys(%hash_name) выдает список всех текущих ключей в
хеше %hash_name. Если элементы в хеше отсутствуют, функция keys
возвращает пустой список.
Пример:
$test{"abc"} = "cba";
$test{12.7} = 21.7;
@list = keys(%test); # @list = ("abc", 12.7) или (12.4, "abc")
Как и в остальных встроенных функциях круглые скобки не обязательны.
foreach $key (keys %test) {
print "at $key we have $test{$key}\n";
}
В этом примере отдельные элементы хеша интерполируются в строки в
двойных кавычках.
В скалярном контексте функция keys выдает число элементов
хеша.
if(keys( %hash)) {
...
}
#
# or
#
while(keys(%hash) < 10) {
...
}
Если обратится к переменной %hash в скалярном контексте, то
будет возвращено значение ложь или истина (пустой или нет):
if(%hash) { # если истина ...
...
}
Функция values(%hash_name) возвращает список всех текущих
значений хеша в том же порядке, в каком функция keys возвращает
ключи.
%test = (); # empty
$test{"abc"} = "cba";
$test{"def"} = "fed";
@test_values = values(%test); # ("cba", "fed") или ("fed", "cba")
Для выполнения цикла над всем хешем можно использовать функцию
keys, но есть более эффективный способ - функция
each(%hash_name), которая возвращает пару ключ-значение
как двухэлементный список. При каждом вычислении этой функции для
одного хеша возвращяется очередная пара, пока не будут перебраны
все элементы. Если пар больше нет, возвращается пустой список.
while(($first, $last) = each(%test)) {
print "The value of $first is $last";
}
Для удаления элементов хеша используется функция delete.
%test = ("abc", "cba", "12.7", "24.7");
delete $test{"abc"};
Использование среза хеша позволяет обращаться не к одному его
элементу, а одновременно к набору.
$score{"mike"} = 205;
$score{"igor"} = 150;
$score{"nick"} = 30;
# or
($score{"mike"}, $score{"igor"}, $score{"nick"}) = (205, 150, 30);
# or
@score{"mike", "igor", "nick"} = (205, 150, 30); # срез
Можно сочетать использование среза и интерполяции пременных:
@players = qw(mike igor nick);
print "scores are: @score{@players}\n";
Срезы хешей можно использовать для слияния меньшего хеша с большим:
@league{keys %score} = values %score;
В этом примерепри наличии ключей-дубликатов используется значение
из меньшего хеша.