Si llama de empuje con los argumentos de la lista, anexa la primera lista con la lista (s) restante en la pila de manera prudente. Lea acerca de push en Perldoc. Entonces su llamada de push(@table, @row);
está creando una lista más larga @table
, no una matriz bidimensional.
Ha recibido varias publicaciones que presionar una referencia de lista como @row
como \@row
creará una lista de filas, y de hecho eso funciona. Tiendo a hacerlo un poco diferente.Por supuesto, con Perl, ¡siempre hay otra manera de hacerlo!
Sintácticamente, también puede insertar una referencia de matriz anónima en el elemento escalar de una lista para crear una lista de múltiples dimensiones. Lo más importante que debe saber sobre las referencias en Perl es: 1) son escalares y 2) pueden referirse a cualquier cosa en Perl: código, matriz, hash, otra referencia. Pase algún tiempo con el Perl Ref Tutorial y esto será más claro. Con su código, simplemente agregue [ ]
alrededor del elemento que desea que sea la 2da dimensión en su lista, así que push(@table, @row);
debe ser push(@table, [ @row ]);
En el mismo sentido, usted pone [ ]
alrededor de su división para que se convierta en push(@table, [ split(/\s*,\s*/, $_) ]);
Esto simultáneamente realizará la división y creará una matriz anónima para el resultado.
El problema específico que tiene, cómo crear y acceder a una lista multidimensional, también se trata muy bien en Tom Christensen's perllol tutorial Las soluciones a sus problemas específicos con su código se tratan directamente aquí.
volver a escribir el código con el código exacto del ejemplo de Tom en perllol, se convierte en esto:
#!/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,0
+1 para no desperdiciar el tiempo de todos omitiendo 'uso estricto; usa advertencias; '. – Ether
Realmente debería evitar 2 argumentos 'abiertos'. Tiene una serie de problemas que es mejor evitar (para más información, consulte esta publicación de perlmonks de 2001: http://www.perlmonks.org/?node_id=131085) Vea esta publicación de SO para obtener información sobre los controles léxicos: http: // stackoverflow .com/questions/613906/why-does-programming-perl-use-local-not-my-for-filehandles – daotoad
Ver ['perldoc perllol'] (http://perldoc.perl.org/perllol.html#Access e impresión) - Accediendo e imprimiendo – Zaid