Если вы вызываете push с аргументами списка, вы добавляете первый список с остальными списками в стеке.Читайте о push на Perldoc .Таким образом, ваш вызов push(@table, @row);
создает более длинный список @table
, а не двумерный массив.
Вы получили несколько сообщений о том, что при нажатии ссылки списка на @row
как \@row
будет создан список строк, и это действительно работает.Я склонен делать это немного по-другому.Конечно, с Perl всегда есть другой способ сделать это!
Синтаксически, вы также можете вставить анонимную ссылку на массив в скалярный элемент списка, чтобы создать многомерный список.Самое важное, что нужно знать о ссылках в Perl: 1) они являются скалярами и 2) они могут ссылаться на что угодно в Perl - код, массив, хэш, другую ссылку.Потратьте некоторое время на Perl Ref Tutorial , и это станет более понятным.С вашим кодом просто добавьте [ ]
вокруг элемента, которым вы хотите быть вторым измерением в вашем списке, так что push(@table, @row);
должно быть push(@table, [ @row ]);
В том же смысле вы положите [ ]
вокруг вашего разбиения, чтобы оно стало push(@table, [ split(/\s*,\s*/, $_) ]);
Это одновременно выполнит разделение и создаст анонимный массив для результата.
Конкретная проблема, с которой вы сталкиваетесь, как создавать многомерный список и получать к нему доступ, также очень хорошо рассматривается в учебнике Тома Кристенсена perllol Решения ваших конкретных проблем с вашим кодом напрямуюздесь.
Переписав свой код с точным кодом из примера Тома в perllol, он становится таким:
#!/usr/bin/perl
use strict;
use warnings;
my (@row, @table, $n, $rowref);
while(<DATA>) {
chomp;
# regex to separate CSV (use of a cpan module for CSV STRONGLY advised...
@row = /(?:^|,)("(?:[^"]+|"")*"|[^,]*)/g;
for (@row) {
if (s/^"//) { s/"$//; s/""/"/g; }
}
push(@table, [ @row ]); #Note the [ ] around the list
}
# Now the table is created, print it:
my $rowcnt=0;
foreach $rowref (@table) {
print "row $rowcnt:\n";
$rowcnt++;
print " [ @$rowref ], \n";
}
# You can access the table in the classic [i][j] form:
for my $i ( 0 .. $#table ) {
$rowref = $table[$i];
$n = @$rowref - 1;
for my $j ( 0 .. $n ) {
print "element $i, $j of table is $table[$i][$j]\n";
}
}
# You can format it:
for my $i ( 0 .. $#table ) {
print "$table[$i][0] $table[$i][1]\n";
print "$table[$i][2]\n";
print "$table[$i][3], $table[$i][4] $table[$i][5]\n\n";
}
__DATA__
Mac,Doe,120 jefferson st.,Riverside, NJ, 08075
Jack,McGinnis,220 hobo Av.,Phila, PA,09119
"John ""Da Man""",Repici,120 Jefferson St.,Riverside, NJ,08075
Stephen,Tyler,"7452 Terrace ""At the Plaza"" road",SomeTown,SD, 91234
,Blankman,,SomeTown, SD, 00298
"Joan ""Joan, the bone""",Jett,"9th, at Terrace plc",Desert City,CO,00123