#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 — это скаляр, содержащий ссылку.