Perl: нарезка массива хэшей

#arrays #perl #slice

#массивы #perl #нарезать

Вопрос:

Вывод кода ниже всегда пуст. Не уверен, что я делаю неправильно, и был бы признателен за любую помощь. Как мне получить значения ключа в определенном хэше в массиве хэшей?

 use strict;
use warnings;

my %dot1 = ('a'=>1,'b'=>2);
my %dot2 = ('a'=>3,'b'=>4);
my %dot3 = ('a'=>5,'b'=>6);
my %dot4 = ('a'=>7,'b'=>8);

my @array = (%dot1,%dot2,%dot3,%dot4);

my %x = $array[2];
my $y = $x->{'a'};

print "$y n";
 

Комментарии:

1. В вашем коде есть синтаксические ошибки.

2. Вы должны получать ошибку компиляции с этим кодом; x это хэш, а не ссылка на хэш. Кроме того, array это не массив из 4 ссылок на хэши; это массив из 16 скаляров.

3. @array это не массив хэшей. Это плоский массив из 16 элементов.

4. Плоский массив скаляров — какой метод / структуру я могу сделать для размещения четырех хэшей?

5. Сколько раз мне нужно рекомендовать вам прочитать perldoc perldsc ? 🙂

Ответ №1:

У вас нет массива хэшей. У вас есть массив, который выглядит как хэш, где ключи a и b будут там по четыре раза каждый, в относительно случайном порядке.

 print Dumper @array;
$VAR1 = [
          'a',
          1,
          'b',
          2,
          'a',
          3,
          'b',
          4,
          'a',
          5,
          'b',
          6,
          'a',
          7,
          'b',
          8
        ];
 

После этого вы используете $x->{a} , который является синтаксисом для получения ключа a из hashref $x , но вы только когда-либо объявляли хэш %a . Это, в свою очередь, прерывается, потому что вы даете ему список нечетного размера с одним значением.

Вместо этого добавьте ссылки на хэши в свой массив. Таким образом, вы получите многоуровневую структуру данных вместо плоского списка. Затем сделайте x переменную скалярной $x .

 my %dot1 = ('a'=>1,'b'=>2);
my %dot2 = ('a'=>3,'b'=>4);
my %dot3 = ('a'=>5,'b'=>6);
my %dot4 = ('a'=>7,'b'=>8);

my @array = (%dot1,%dot2,%dot3,%dot4); # here


my $x = $array[2]; # here
my $y = $x->{'a'};

print "$y n";
 

Это приведет к печати 5 .

Вам следует ознакомиться со структурами данных в perlref и perlreftut.

Комментарии:

1. Очень понятно. А теперь посмотрите, как также проясняется часть с нулевым основанием. Большое спасибо @simbabque.

Ответ №2:

Если вам нужен массив ссылок на хэши, вам нужно явно указать это.

 my @array = (%dot1, %dot2, %dot3, %dot4);
my %x = %{$array[2]};
my $y = $x{a};
print "$yn";
 

Комментарии:

1. Спасибо @chepner. Поймите часть %{$array[2]}.

2. Я разыменовываю ссылку на хэш, чтобы мы могли назначить фактическое hash значение %x . Вы также можете работать непосредственно со ссылкой с $my x = $array[2]; my $y = $x->{a} помощью . Ключевым моментом является сохранение ссылок на хэши в массиве вместо хранения расширенного содержимого каждого хэша в массиве.

Ответ №3:

Что вы хотите сделать, это добавить ссылки на ваши хэши к вашим @array , в противном случае perl будет оценивать хэши в контексте списка.

 my @array = (%dot1,%dot2,%dot3,%dot4);
my $x = $array[2];
my $y = $x->{'a'};

print "$y n";
 

Комментарии:

1. Спасибо @sparkeyG. Теперь я вижу проблему.

2. Хотя я не совсем уверен, что понимаю значение $ x, поскольку $array[2] — это не скаляр, а % dot2. Кроме того, просто хочу подтвердить, что в Perl массивы и хэши не начинаются с нуля, верно?

3. Значение at $array[2] является ссылкой на %dot3 (обратите внимание, что ссылки на массивы в perl равны нулю.) $ x — это скаляр, содержащий ссылку.