$variable # скалярная переменная
@variable # переменная-массив
%variable # переменная-хэш
Типичным применением хэша можно считать составление частотного словаря, в котором со значением каждого слова ассоциируется счетчик его появления в тексте. Для простоты предположим, что слова в файле, содержащем текст, разделены только пробелами:
while (my $line = <>) { # считать строку из входного потока
chomp($line); # удалить из строки символ '\n'
@words = split(' ', $line); # разбить строку на слова
foreach my $word (@words) { # для каждого найденного слова
$hash{$word}++; # увеличить счетчик
}
}
# теперь в %hash содержатся счетчики слов
Позднее, в лекции, посвященной регулярным выражениям, будет сказано, как выделять из строки слова не только по пробелам.
Как это было сделано в последнем примере, программисты часто пользуются уникальностью ключей в хэше, чтобы исключить дублирование данных. Для удаления из данных повторений достаточно поместить их в хэш в качестве ключей. При этом даже не обязательно ассоциировать с ключами какие-либо значения. В результате набор ключей хэша будет гарантированно содержать только неповторяющиеся значения из обработанного набора данных.
При обработке данных в хэше часто возникает необходимость проверить наличие в нем элемента с определенным ключом. Функция exists проверяет, содержится ли указанный ключ в хэше. Если ключ найден, она возвращает истинное значение ('1'), - и ложное значение (пустую строку), если такого ключа в хэше нет. При этом ассоциированное с ключом значение не проверяется и может быть любым, в том числе и неопределенным. Так можно проверить наличие ключа в хэше:
print "ключ $key найден" if exists $hash{$key};
При помощи функции defined() , возвращающей истинное или ложное значение, можно проверить, было ли задано значение в элементе хэша, ассоциированное с указанным ключом, или оно осталось неопределенным. Например:
print "с ключом $key связано значение" if defined $hash{$key};
Проверка с помощью функции defined($hash{$key}) отличается от проверки значения элемента на истинность значения $hash{$key} , так как значение элемента может быть определено, но равно нулю или пустой строке, что тоже воспринимается как ложь.
Воспользовавшись функцией undef() , можно удалить из хэша только значение элемента, не удаляя его ключа, то есть сделать его неопределенным:
undef $hash{$key }; # сделать значение неопределенным
После того как значение элемента было удалено функцией undef() , проверки наличия в хэше ключа и значения указанного элемента хэша дадут следующие результаты:
$hash{$key} # неопределенное значение - это ложь
defined $hash{$key} # ложь, ибо значение не определено
exists $hash{$key} # истина, ибо ключ есть
Неопределенное значение, хранимое в элементе хэша, означает, что необходимый поисковый ключ присутствует, но с ним не ассоциировано никакого значения.
Добавление элементов в хэш выполняется операцией присваивания, а удаление - функцией delete . Эта функция по указанному элементу удаляет из хэша соответствующую пару "ключ - значение" и возвращает только что удаленное значение. Это делается так:
$deleted_value = delete $hash{$key}; # удалить элемент
Если аргументом функции delete будет несуществующий элемент массива, то она просто вернет неопределенное значение, не вызвав ошибки при выполнении программы.
При работе с элементами хэша очень удобно иметь список всех его ключей. Его возвращает функция keys . Полученный список можно сохранить в массиве для дальнейшей обработки:
@hash_keys = keys %hash; # поместить список ключей в массив
Возможно также использовать список ключей для доступа в цикле ко всем значениям хэша. Так можно напечатать частотный словарь из предыдущего примера:
foreach my $word (keys %hash) { # для каждого ключа хэша
print "$word встретилось $hash{$word} раз\n";
}
Элементы хэша, как и другие скалярные величины, помещенные в обрамленную двойными кавычками строку, заменяются своими значениями. Кстати, можно переписать последний пример, добавив сортировку ключей для вывода слов в алфавитном порядке. А для организации цикла можно применить модификатор foreach , совмещающий очередной элемент списка с переменной по умолчанию $_ :
print "$_ встретилось $hash{$_} раз\n"
foreach (sort keys %hash);
Следует помнить, что если размер хэша велик, то и полученный с помощью функции keys массив ключей тоже будет занимать большой объем памяти. В скалярном контексте функция keys возвращает количество ключей в хэше, поэтому с ее помощью можно легко проверить, не пустой ли хэш:
Читать дальше