Se si chiama spinta con argomenti della lista, si aggiunge la prima lista con l'elenco rimanente (s) in pila saggio di moda. Leggi informazioni su push allo Perldoc. Quindi la tua chiamata di push(@table, @row);
sta creando un elenco più lungo @table
, non un array bidimensionale.
Hai ricevuto diversi post che spingono un riferimento a @row
come \@row
creerà un elenco di righe, e in effetti funziona. Tendo a farlo un po 'diversamente.Ovviamente, con Perl, c'è sempre un altro modo per farlo!
Sintatticamente, è anche possibile inserire un riferimento anonimo dell'array nell'elemento scalare di un elenco per creare un elenco a più dimensioni. La cosa più importante da sapere sui riferimenti in Perl è: 1) sono uno scalare e 2) possono riferirsi a qualsiasi cosa in Perl - codice, array, hash, un altro riferimento. Passa un po 'di tempo con lo Perl Ref Tutorial e questo diventerà più chiaro. Con il tuo codice, aggiungi [ ]
attorno all'elemento che vuoi essere la seconda dimensione nell'elenco, quindi push(@table, @row);
dovrebbe essere push(@table, [ @row ]);
Nello stesso senso, devi inserire [ ]
intorno allo split in modo che diventi lo push(@table, [ split(/\s*,\s*/, $_) ]);
allo stesso tempo. una matrice anonima al risultato.
Il problema specifico che si ha, come creare e accedere a un elenco multidimensionale, è anche trattato molto bene in perllol tutorial di Tom Christensen. Le soluzioni ai problemi specifici con il codice vengono trattate direttamente qui.
riscrivere il codice con il codice esatto dall'esempio di Tom in perllol, diventa in questo modo:
#!/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 per non sprecare il tempo di tutti omettendo 'use strict; usare avvertenze; '. – Ether
Dovresti davvero evitare 2 argomenti 'apri'. Ha un numero di problemi che è meglio evitare (per la discussione vedi questo post perlmonks del 2001: http://www.perlmonks.org/?node_id=131085) Vedi questo post SO per informazioni sugli handle lessicali: http: // stackoverflow .com/questions/613906/why-does-programming-perl-use-local-not-my-filehandles – daotoad
Vedere ['perldoc perllol'] (http://perldoc.perl.org/perllol.html#Access -e-Stampa) - Accesso e stampa – Zaid