The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

Хэш хэшей в Perl - вложенные массивы и хеши (perl hash)


<< Предыдущая ИНДЕКС Поиск в статьях src Установить закладку Перейти на закладку Следующая >>
Ключевые слова: perl, hash,  (найти похожие документы)
Date: Wed, 17 Apr 2002 11:39:00 +0400 From: Bulat Ziganshin <[email protected]> Newsgroups: fido7.ru.perl Subject: Хэш хэшей в Perl - вложенные массивы и хеши VP>> my %hash2 = qw(d 3 e 4); VP>> $hash1{'c'} = \%hash2; AM> А %hash2 можно динамически создавать по мере появления новых ключей у AM> %hash1? не всегда :) есть perldsc, вот его кратокое изложение === Cut === ну очень краткое :) итак, как работать в perl с вложенными массивами и хешами до perl5 в перле было всего три (основных) типа данных и имя переменной полностью определяло, данные какого типа она хранит $x - хранит ЗHАЧЕHИЕ (число или строку) @x - хранит список ЗHАЧЕHИЙ %x - хранит список пар строка->ЗHАЧЕHИЕ в perl5 всё осталось также, только понятие ЗHАЧЕHИЯ было расширено - теперь это может быть ССЫЛКА на массив или хеш. очень важная тонкость - в отличие от самого массива или хеша, ССЫЛКА на них является скаляром. вот смотрите: @a = (1,2); $a = [ (1,2) ]; # квадратные скобки превращают массив/хеш в ССЫЛКУ на массив %b = (1=>2); $b = { (1=>2) }; # фигурные скобки превращают массив/хеш в ССЫЛКУ на хеш обратите внимания - круглые скобки используются только для группировки, а квадратные и фигурные являются ОПЕРАТОРОМ, превращающим СОСТАВHОЕ ЗHАЧЕHИЕ в ССЫЛКУ. Внутри []/{} круглые скобки обычно опускают, я привёл их лишь для удобства понимания единственной существенной разницы между этими действиями теперь несложно сконструировать массив массивов: @c = ( [1,2], [2], [3,4,5] ); на самом деле, конечно, это массив ССЫЛОК на массивы. но к его элементам можно обращаться, не задумываясь об этом - $c[0][1] или создадим хеш хешей: %d = ( C=> {Speed=>Good, Readability=>Bad}, Perl=>{Speed=>hmmm} ); опять же, $d{Perl}{Speed} будет работать если же вы и внешние круглые скобки замените на []/{}, то опять получите скаляр, и его надо будет присваивать тоже скаляру: $e = [ [1,2], [3,4] ]; # ССЫЛКА на массив, состоящий из ССЫЛОК на массивы поскольку перловые функции обычно ожидают "развёрнутый" массив/хеш, пользоваться таким скаляром будет неудобно. да и к элементам его доступ неочевиден - $e->[0][1]. собственно, "->" - оператор разыменования ССЫЛОК, и для доступа к элементам @c он тоже используется, но перл вставляет его неявно: $c[0][1] эквивалентно $c[0]->[1]. То есть, $c[0] возвращает нам ССЫЛКУ на массив, стрелка её разыменовывает (превращает ССЫЛКУ в массив) и затем второе индексирование "[1]" возвращает нам элемент этого массива наверно, уже понятно, что $e->[0][1] на самом деле работает как $e->[0]->[1]: разыменовываем, берём элемент, снова разыменовываем, и снова берём элемент. с массивами хешей, и со сколь угодно более сложными структурами данных всё точно также. разумеется, их можно произвольно смешивать: $a = [ 1, [2,3], {a=>b}, [[4,5]] ]; 1 == $a->[0] 2 == $a->[1][0] b == $a->[2]->{a} == $a->[2]{a} 5 == $a->[3][0][1] вот, в общем-то, и всё. добавлю несколько дополнительных замечаний операторы []/{} создают КОПИИ переданных им ЗHАЧЕHИЙ. если вы хотите вместо этого получить ССЫЛКУ на ТЕ ЖЕ данные, используйте оператор "\". кстати, эти операторы можно комбинировать: @a = (1,2); @b = (3,4); @c = ( [@a], [@b] ); # @c содержит (ССЫЛКИ на) копии массивов a и b @d = ( \@a, \@b ); # @d содержит ССЫЛКИ на массивы a и b @e = ( [\@a, \@b], [[@a], [@b]] ); @e - трёхмерный массив, $e[0][0][$i] эквивалентно $a[$i] $e[0][1][$i] эквивалентно $b[$i] $e[1][0][$i] содержат копии $a[$i] $e[1][1][$i] содержат копии $b[$i] т.е. теперь присваивания $a[$i] изменят также ЗHАЧЕHИЯ $d[0][$i] и $e[0][0][$i] и наоборот. ссылки полезны при передаче сложных структур данных в функции (чтоб перл не разворачивал всё в один бессмысленный список) и при манипуляциях со связными структурами данных, типа деревьев и связных списков не используйте операцию получения ссылки без необходимости, поскольку перл возвращает ССЫЛКУ не на данные как таковые, а на переменную, и в дальнейшем что бы ни присвоили этой переменной - вы увидите это по своей ссылке: @a = (1,2); $ref = \@a; @a = (3,4); # теперь $ref указывает на новое содержимое @a второе замечание - многие встроенные операторы перла рассчитаны на то, что им на вход подадут переменную-массив или хеш. но никак не ССЫЛКУ. для того, чтобы превратить одно в другое, используются конструкции @{...} и %{...}: push @{$c[0]}, 0; # $c[0] - ССЫЛКА на массив, @{$c[0]} - сам массив %d = ( C=> {Speed=>Good, Readability=>Bad}, Perl=>{Speed=>hmmm} ); print keys %{$d{C}} # $d{C} - ССЫЛКА на хеш, %{$d{C}} - сам хеш остатнее читайте в perldsc. там же есть готовые куски кода для всех возможных манипуляций с массивами массивов, массивами хешей, хешами массивов и хешами хешей. от себя посоветую использовать модуль Data::Dumper для изучения результатов своего творчества :) use Data::Dumper; # for exporting values from Perl to Ruby #$Data::Dumper::Indent = 0; # one-line output #$Data::Dumper::Terse = 1; # print no assignments to $VARn #$Data::Dumper::Useqq = 1; # quote unprintable chars #$Data::Dumper::Deepcopy = 1; # ??? are we really need this? ;) print Dumper(\$a), "\n", Dumper(\@e), "\n", Dumper(\%d); === Cut === Bulat, mailto:bulatz-AT-fort.tatarstan.ru, ICQ: work 15872722, home 11849833 ... Иногда для того, чтобы изменить свое восприятие мира, ... люди пытаются изменить сам мир

<< Предыдущая ИНДЕКС Поиск в статьях src Установить закладку Перейти на закладку Следующая >>

 Добавить комментарий
Имя:
E-Mail:
Заголовок:
Текст:




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру