Если вы используете push
, вы не должны использовать знак равенства (если только вы не хотите, чтобы количество элементов было перемещено). Это говорит мне, что там есть проблема. Вы, вероятно, немного запутались в своей структуре. Вы либо помещаете данные в свою ссылку на массив, либо хотите объединить элементы и поместить их в другую структуру. То, что вы написали, немного сложно понять, потому что синтаксис может быть очень сложным для понимания.
Похоже, вы хотите поиграть со ссылками и посмотреть, сможете ли вы их освоить. Когда вы имеете дело со сложными структурами, подобными этой, легче понять, если у вас есть какие-то... ммм... данные из реального мира. Давайте создадим реальный хэш хэша массивов, и его будет немного легче отслеживать.
Давайте сделаем хэш, содержащий людей. Хэш будет содержать данные и будет содержать имя человека. Мы назовем это %people
. В нашем хеше будет два человека, Боб и Джанет. У Боба и Джанет разные адреса и номера телефонов. У нас будет ссылка на хэш, который будет содержать имена наших полей данных с именами PHONE
и ADDRESS
.
$people{Bob}->{ADDRESS}; # Bob's addresses
$people{Bob}->{PHONE}; # Bob's phone numbers
$people{Janet}->{ADDRESS}; # Janet's Addresses
$people{Janet}->{PHONE}; # Janet's Phone numbers
Обратите внимание на синтаксис стрелки. Это говорит вам, что $people{Bob}
содержит ссылку на другой хэш, а не просто скалярные данные.
Далее, у Боба и Джанет может быть несколько адресов и телефонных номеров, поэтому вместо хранения одного телефонного номера у нас будет $people{Bob}->{PHONE}
для хранения ссылки на массив телефонных номеров, а $people{Bob}->{ADDRESS}
будет содержать ссылку на массив адресов.
Вот короткая программа, которая считывает данные. Каждый раз, когда строка начинается с person:
, я предполагаю, что следующие данные будут для этого человека. У человека могут быть адреса и телефоны. Я буду хранить их в виде массивов под правильным хешем.
Как сказал Икегами, в Perl есть то, что называется авто-оживлением, что позволяет Perl точно определить, на какой тип ссылки вы указываете. Тем не менее, мне нравится заявлять, что я ожидаю от структуры данных для целей документации. Следующие операторы в моей программе на самом деле не нужны, но я нахожу их полезными:
$people{$person} = {}; # This is a reference to another array
и
if ( not exists $people{$person}->{ADDRESS} ) {
$people{$person}->{ADDRESS} = []; #This is a reference to an array
}
Вот моя программа:
#! /usr/bin/env perl
#
use strict;
use warnings;
use Data::Dumper;
use feature qw(say);
my %people;
my $person;
while ( my $line = <DATA> ) {
chomp $line;
my ( $type, $data ) = split /:\s*/, $line;
if ( $type eq "person" ) {
$person = $data;
$people{$person} = {}; # This is a reference to another array
}
if ( $type eq "address" ) {
if ( not exists $people{$person}->{ADDRESS} ) {
$people{$person}->{ADDRESS} = []; #This is a reference to an array
}
push @{ $people{$person}->{ADDRESS} }, $data;
}
if ( $type eq "phone" ) {
if ( not exists $people{$person}->{PHONE} ) {
$people{$person}->{PHONE} = []; #This is a reference to an array
}
push @{ $people{$person}->{PHONE} }, $data;
}
}
say Dumper \%people;
__DATA__
person: Bob
address: 120 Main Street, Suburbville CO
address: 123 Wage Slave Lane, Industry CO
address: 1 Beach Hut Road, Getaway CA
phone: 555-1111
phone: 555-2222
person: Janet
address: 230 Oak Tree Road, Gloomsburg CO
address: 544 Initech Road, Businesstown CO
phone: 555-3333
phone: 555-4444
Это производит:
$VAR1 = {
'Bob' => {
'PHONE' => [
'555-1111',
'555-2222'
],
'ADDRESS' => [
'120 Main Street, Suburbville CO',
'123 Wage Slave Lane, Industry CO',
'1 Beach Hut Road, Getaway CA'
]
},
'Janet' => {
'PHONE' => [
'555-3333',
'555-4444'
],
'ADDRESS' => [
'230 Oak Tree Road, Gloomsburg CO',
'544 Initech Road, Businesstown CO'
]
}
};
person
David W.
schedule
06.01.2014