2008-11-25 12 views
18

Ich bin ein bisschen neu zu Perl, aber hier ist es, was ich tun möchte:Wie kann ich mehrdimensionale Arrays in Perl erstellen?

my @array2d; 
while(<FILE>){ 
    push(@array2d[$i], $_); 
} 

Es kompilieren nicht, da @array2d[$i] kein Array ist, sondern ein Skalarwert.

Wie soll ich @ array2d als Array Array deklarieren?

Natürlich habe ich keine Ahnung, wie viele Zeilen ich habe.

Antwort

27

Um ein Array von Arrays, oder genauer gesagt eine Reihe von arrayrefs zu machen, versuchen, etwas wie folgt aus:

my @array =(); 
foreach my $i (0 .. 10) { 
    foreach my $j (0 .. 10) { 
    push @{ $array[$i] }, $j; 
    } 
} 

Es drückt den Wert auf einen dereferenzierte ArrayRef für Sie.

print $array[3][2]; 
+4

Sie auch als $ Array zugreifen können [3] [2] - der Pfeil ist nicht erforderlich zwischen aufeinanderfolgenden [n] oder {key} Indizes von mehrstufigen Datenstrukturen. – xdg

+0

Sie haben Recht, danke für die Info. Ich werde die Antwort aktualisieren, um das zu reflektieren. – gpojd

6

Werfen Sie einen Blick auf perlref und perldsc, um zu sehen, wie verschachtelte Datenstrukturen, wie Arrays von Arrays und Hashes von Hashes gemacht werden. Sehr nützliche Sachen, wenn Sie Perl machen.

8

Ändern Sie Ihre „Push“ Linie dazu: Sie sollten einen Eintrag wie diesen zugreifen können

push(@{$array2d[$i]}, $_); 

Sie machen im Grunde $ array2d [$ i] ein Array von ihm umgeben von das @ {} ... Sie können dann Elemente auf dieses Array von Array-Referenzen schieben.

+1

Gute Erklärung. Um weiter zu klären, ist $ array2d [$ i] eine Array-Referenz. In @ {$ array2d [$ i]} gibt der {} -Block den Array-Verweis zurück und das @ sigil-Element gibt den Wert als Array zurück. Ich weise darauf hin, um zu verdeutlichen, dass die geschweiften Klammern ein bloßer Block sind und kein Mittel, um die Rangfolge zu untergraben. – converter42

+0

Danke für die Erklärung meiner Erklärung - ich wusste, dass es funktioniert hat, aber ich wusste nie die technischen Gründe dafür. Vielen Dank! – BrianH

+0

Nein, sie sind ein Dereferenzierungsblock, kein bloßer Block. In perl -wle '{1 if @ {; last}; print "in"} print "out" ', der letzte sieht den äußeren, wirklich kahlen Block, nicht den inneren Block. – ysth

0

Eine weitere einfache Möglichkeit ist es, eine Hash-Tabelle zu verwenden und den zwei Array-Indizes verwenden, um einen Hash-Schlüssel zu machen:

$two_dimensional_array{"$i $j"} = $val; 
+0

Es gibt tatsächlich einen alten syntaktischen Zucker dafür: http://perldoc.perl.org/perldata.html # Multi-dimensionale-Array-Emulation - so können Sie einfach '$ two_dim_array {$ i, $ j} = $ val' –

3

Es gibt wirklich keinen Unterschied zwischen dem, was Sie geschrieben haben und diese:

@{$array2d[$i]} = <FILE>; 

Ich kann nur davon ausgehen, dass Sie Dateien durchlaufen.

Um die Verfolgung eines Zählers zu vermeiden, können Sie dies tun:

... 
push @array2d, [ <FILE> ]; 
... 

Das 1 sagt) einen Verweis auf ein leeres Array erstellen, 2) alle Zeilen in der Datei zu speichern, 3) aufstecken @array2d .

+0

Ich finde diese Syntax wirklich hervorragend. Gute Lösung. –

0

Wenn Sie nur eine Datei in einem Array zu speichern versuchen, können Sie auch dies tun:

fopen(FILE,"<somefile.txt"); 
@array = <FILE>; 
close (FILE); 
Verwandte Themen