2016-09-08 5 views
0

Es scheint nicht zu viele Beispiele von Menschen mit Arrays mit Hashes. Ich möchte das Array überprüfen, das ich in einem Unterbau baue, aber ich habe einige Probleme beim Zugriff auf die Struktur. Vielleicht stelle ich mir das Konstrukt nicht so vor, wie es existiert. Dies ist ein Beispiel von Code:Perl: How to print Array von Hashes,

#!/usr/bin/perl 

use strict; 
use warnings; 
use Data::Dumper; 


my (%data, %data2, @holding); 

%data = (
    'monday' => "This stuff!", 
    'tuesday' => "That stuff!!", 
    'wed' => "Some other stuff!!!" 
    ); 

push @holding, %data; 

%data2 = (
    'monday' => "Yet more stuff... :-P ", 
    'tuesday' => "Some totally different stuff!", 
    'wed' => "What stuff is this?" 
    ); 

push @holding, %data2; 

foreach my $rows(@holding){ 
    foreach my $stuff (keys %{$holding[$rows]}){ 
     print "$holding[$rows]{$stuff}\n"; 
    } 
} 

Die Fehlermeldung erhalte ich:

Argument "wed" isn't numeric in array element at /home/kingram/bin/test line 27. 
Can't use string ("wed") as a HASH ref while "strict refs" in use at /home/kingram/bin/test line 27. 

Meine Arbeit mit Arrays in Perl ist nicht sehr umfangreich, so bin ich sicher, ich etwas Grundsätzliches bin fehlt.

Wenn ich Dumper Ich erwarte VAR1 und VAR2 zwei verschiedene Reihen ausdrücken, aber ich bekomme

$ ~/bin/test 
$VAR1 = [ 
      'wed', 
      'Some other stuff!!!', 
      'monday', 
      'This stuff!', 
      'tuesday', 
      'That stuff!!', 
      'wed', 
      'What stuff is this?', 
      'monday', 
      'Yet more stuff... :-P ', 
      'tuesday', 
      'Some totally different stuff!' 
     ]; 

Antwort

5

Sie müssen sich mit Referenzen arbeiten. Wenn Sie einen Hash in ein Array eingeben, ist dies nur eine flache Liste. Sie verwenden die richtigen Dereferenzierungsoperatoren in Ihrer Schleife, aber beim Drücken fehlt ein Backslash \.

push @holding, \%data; 

Der Backslash \ gibt Ihnen einen Verweis auf %data, die ein skalarer Wert ist. Das wird in dein Array geschoben.

Siehe perlreftut für eine Erklärung.


Wenn Sie bei @holding nach dem zwei push Operationen aussehen, es ist offensichtlich, was passiert.

use Data::Printer; 
p @holding; 

__END__ 
[ 
    [0] "monday", 
    [1] "This stuff!", 
    [2] "tuesday", 
    [3] "That stuff!!", 
    [4] "wed", 
    [5] "Some other stuff!!!", 
    [6] "wed", 
    [7] "What stuff is this?", 
    [8] "monday", 
    [9] "Yet more stuff... :-P ", 
    [10] "tuesday", 
    [11] "Some totally different stuff!" 
] 
+1

Ah. Recht. Ich habe das "\" falsch verstanden. Danke für diesen Einblick. Ziemlich einfach, sehr einfach, am wichtigsten. –

1

Selbst wenn Sie die Datenstruktur richtig zu machen, wird dieser Code noch nicht zur Arbeit zu gehen:

foreach my $rows(@holding){ 
    foreach my $stuff (keys %{$holding[$rows]}){ 
     print "$holding[$rows]{$stuff}\n"; 
    } 
} 

Wenn Sie foreach my $rows (@holding) verwenden über den Array zu durchlaufen, jedes Mal durch die Schleife $rows enthalten ein Element aus dem Array, nicht der Index eines Elements. Sie müssen also nicht mit $holding[$rows] nachschlagen. Ihr Code sollte folgendermaßen aussehen:

foreach my $rows (@holding){ 
    foreach my $stuff (keys %{$rows}){ 
     # $rows will contain a hash *reference*. 
     # Therefore use -> to access values. 
     print "$rows->{$stuff}\n"; 
    } 
}