Как бы использовать срез хеша для инициализации хеша, хранящегося в структуре данных? - PullRequest
6 голосов
/ 24 августа 2010

В предыдущем вопросе я спросил, как инициализировать хэш Perl, используя слайсы.Это делается так:

my %hash = ();
my @fields = ('currency_symbol', 'currency_name');
my @array = ('BRL','Real');
@hash{@fields} = @array;

Теперь давайте представим более сложный хеш, и вот как он инициализируется:

my %hash = ();
my $iso = 'BR';
$hash->{$iso}->{currency_symbol} = 'BRL';
$hash->{$iso}->{currency_name} = 'Real';
print Dumper($hash);

Это приводит к следующему:

$VAR1 = {
          'BR' => {
                    'currency_symbol' => 'BRL',
                    'currency_name' => 'Real'
                  }
        };

Теперь возникает вопрос: как инициализировать этот конкретный хеш, используя метод соединения?

Ответы [ 3 ]

3 голосов
/ 24 августа 2010

Раздел Slices документации perllol охватывает фрагменты массива:

Если вы хотите получить срез (часть строки) в многомерном массиве, вам придется выполнить некоторую причудливую подписку. Это потому, что хотя у нас есть хороший синоним для отдельных элементов через стрелку указателя для разыменования, для слайсов такого удобства не существует. (Помните, конечно, что вы всегда можете написать цикл для выполнения операции среза.)

Вот как выполнить одну операцию, используя цикл. Мы примем переменную @AoA, как и раньше.

@part = ();
$x = 4;
for ($y = 7; $y < 13; $y++) {
  push @part, $AoA[$x][$y];
}

Тот же цикл можно заменить операцией среза:

@part = @{ $AoA[4] } [ 7..12 ];

Экстраполируя на хеш-фрагменты, получаем

@{ $hash{$iso} }{@fields} = @array;

Вы знаете, что это фрагмент хеша, потому что «индексы» заключены в фигурные скобки, а не в квадратные скобки.

2 голосов
/ 24 августа 2010

Прежде всего, поскольку ваш хеш объявлен %hash, он будет просто $hash{ $iso }.$hash->{ $iso } относится к слоту в хэше, указанному $hash, который может указывать или не указывать на %hash.

Но как только вы это сделаете, вы можете сделать следующее:

@{ $hash{ $iso } }{ @fields } = qw<BRL Real>;

Но когда уровни скоро станут сложными, лучше отказаться от роскоши автовивификации и сделать следующее:

my $h = $hash{ $iso }{blah}{blah} = {};
@$h{ @field_names } = @field_values;

Перемещаемые указатели в иерархии хешей облегчают написание анонимных обращений, которые также допускают легкие срезы.

1 голос
/ 24 августа 2010

$hash{$iso} будет хеш-ссылкой. Вы заменяете то, что будет именем переменной (без сигилы) в простом срезе блоком, содержащим ссылку, так:

@array{@list}

становится

@{ $hash{$iso} }{@list}

См. http://perlmonks.org/?node=References+quick+reference

...