Работа с массивами в Perl
Преобразуем обычный массив в хэш-массив:
%hash = map { $_, 1 } @array;
Например:
%hash = map { $_, 1 } qw(a b c);
Этот оператор преобразует массив ('a', 'b', 'c') в хэш-массив ('a', 1', 'b', 1, 'c', 1). Русть мы имеем лог httpd примерно следующего содержания
host.com.de - - [08/Jan/2007:01:50:42 -0700] "GET /index.html HTTP/1.0" 200 6798
host.org.ch - - [08/Jan/2007:01:53:21 -0700] "GET /index.php HTTP/1.0" 200 10002
и нам нужно сделать хэш-массив, состоящий из первых слов каждой строки (в данном случае - имя домена), а значением элемента массива - количество повторений этого слова
@host{/^(\S+)/}++ while <>;
Этот же фрагмент кода можно переписать и в более привычном виде
while (<>) { # Считываем строку в переменную $_
my ($addr) = /^(\S+)/; # Получаем первое слово строки
$host{$addr}++; # Увеличиваем счетчик повторений слова
}
Вот еще подобный фрагмент кода
%host = map {/^(\S+)/, 1} <>;
Но в этом случае содержимое всего файла считывается в память (<> в контексте списка) перед тем, как продолжить вычисления. Это может быть оправдано в случае небольших размеров файла. Инверсия хэш-массива один-к-одному
Предположим, мы имеем хэш-массив, с информацией о соответствии IP адресов и символьных имен
%num_to_host = (
'123.234.3.1' => 'george',
'123.234.3.2' => 'Alex',
'123.234.3.3' => 'judy'
);
Таким образом, используя адрес IP в качестве индекса можно получить его символьное имя, то есть значение. А как выполнить обратную процедуру?
%host_to_num = reverse %num_to_host;
В случае хэш-массива с отношением один-к-одному мы получим хэш-массив с обратным соответствием, т.е. сможем определять IP адрес имея его символьное имя.
('george' => '123.123.3.1',
'Alex' => '123.234.3.3',
'jane' => '123.234.3.2')