Rekursiv drucken Datenstrukturen in Perl
Ich bin zurzeit learning Perl. Ich habe Perl hash, das Referenzen auf hashes und arrays. Die hashes und arrays können wiederum Referenzen auf andere hashes/arrays.
Schrieb ich eine Unterroutine, die zum analysieren der hash rekursiv und drucken Sie Sie mit der richtigen Einrückung. Obwohl die routine funktioniert wie erwartet, mein Lehrer war nicht davon überzeugt, über die Lesbarkeit und Eleganz des folgenden code.
Ich würde wirklich zu schätzen, um die Ansichten der Perl-Profis hier auf mögliche Optimierung der code unten.
Hier ist mein vollständiger code-snippet..
# Array of Arrays
$ref_to_AoA = [
[ "fred", "barney" ],
[ "george", "jane", "elroy" ],
[ "homer", "marge", "bart" ],
];
#Array of Hashes
$ref_to_AoH = [
{
husband => "barney",
wife => "betty",
son => "bamm bamm",
},
{
husband => "george",
wife => "jane",
son => "elroy",
},
];
# Hash of Hashes
$ref_to_HoH = {
flintstones => {
husband => "fred",
pal => "barney",
},
jetsons => {
husband => "george",
wife => "jane",
"his boy" => "elroy", # Key quotes needed.
},
simpsons => {
husband => "homer",
wife => "marge",
kid => "bart",
},
};
# Hash which contains references to arrays and hashes
$finalHash = {
'arrayofArrays' => $ref_to_AoA,
'arrayofHash' => $ref_to_AoH,
'hashofHash' => $ref_to_HoH,
};
$string = str($finalHash);
print "$string\n";
#------------------------------------------------------------------
sub str {
my $hash = shift;
my ($space, $newline, $delimiter) = @_;
$space = "" unless (defined $space);
$newline = "\n\n\n" unless (defined $newline);
$delimiter = "\n--------------------------------------------" unless (defined $delimiter);
my $str = "";
for (sort keys %{$hash}) {
my $value = $hash->{$_};
$str .= "$newline$space$_ == $value$delimiter";
$str .= recurseErrors($value,$space);
}
$str;
}
#------------------------------------------------------------------
sub recurseErrors {
my $str;
my ($value,$space) = @_;
my $ref = ref $value;
if ($ref eq 'ARRAY') {
my $i = 0;
my $isEmpty = 1;
my @array = @$value;
$space .= "\t";
for my $a (@array) {
if (defined $a) {
$isEmpty = 0;
$str .= "\n$space$_\[$i\] :";
$str .= recurseErrors($a,$space);
}
$i++;
}
$str .= "= { }" if ($isEmpty);
} elsif ($ref eq 'HASH') {
$space .= "\t";
for my $k (sort keys %$value) {
if ( ( ref($value->{$k}) eq 'HASH') || (ref $value->{$k} eq 'ARRAY') ) {
my $val = $value->{$k};
$str .= "\n\n$space$k == ";
$str .= "$val";
}
else {
$str .= "\n$space$k == ";
}
$str .= recurseErrors($value->{$k},$space);
}
# we have reached a scalar (leaf)
} elsif ($ref eq '') {
$str .= "$value";
}
$str
}
#------------------------------------------------------------------
Ausgabe:
arrayofArrays == ARRAY(0x9d9baf8) -------------------------------------------- arrayofArrays[0] : arrayofArrays[0] :fred arrayofArrays[1] :barney arrayofArrays[1] : arrayofArrays[0] :george arrayofArrays[1] :jane arrayofArrays[2] :elroy arrayofArrays[2] : arrayofArrays[0] :homer arrayofArrays[1] :marge arrayofArrays[2] :bart arrayofHash == ARRAY(0x9d9bba8) -------------------------------------------- arrayofHash[0] : Mann == barney Sohn == Hoppla Hoppla Frau == betty arrayofHash[1] : Mann == george Sohn == elroy Frau == jane hashofHash == HASH(0x9da45f8) -------------------------------------------- flintstones == HASH(0x9d9bb48) Mann == fred pal == barney jetsons == HASH(0x9d9bbf8) seine Jungen == elroy Mann == george Frau == jane simpsons == HASH(0x9d9bc48) Mann == homer Kind == bart Frau == marge
- Ihr Lehrer ist ein Filmfehler. Ihre Präsentation sieht gut aus.
- Bist du sicher, dass dein Lehrer bezog sich nicht auf die Ausgabe?
Du musst angemeldet sein, um einen Kommentar abzugeben.
use strict
;use warnings
als gut.Abgesehen davon, dass ich denke, dass Ihr Lehrer hatte einen schlechten Tag, Tag.
vielleicht Data::Dumper ist, was Sie wollen:
Wenn Sie neu in perl, würde ich empfehlen, läuft dein code durch perl-Kritiker (es gibt auch ein Skript können Sie die Installation von CPAN, normalerweise verwende ich es als einen test, so wird es von der Befehlszeile aus ausgeführt, wenn ich "make test"). Zusätzlich zu seiner Ausgabe, möchten Sie vielleicht eine Pause einlegen und die Funktionen ein bisschen mehr. recurseErrors hat drei Fälle, die könnten aufgeteilt werden in sub-Funktionen (oder sogar in einer hash-ref-type sub-function-ref).
Wenn dies ein Auftrag, den ich verwenden würde,Data::Dumper, aber es klingt wie das ist Hausaufgaben, so dass Ihre Lehrer kann sich nicht zu uns.
Hier ist ein einfaches Beispiel, warum Ihr code nicht so leicht lesbar:
Könnten Sie die
defined or
Betreiber:Wenn Sie besorgt über die früheren Perls:
Bedingungen gehen aus dem rechten Rand genug sind eine Abzweigung für mich nicht zu Lesen, den rest des Codes.
Meine Vermutung ist, dass er nicht mag, dass Sie
str
Funktion.str
, aber nie die zahlen in die endgültige Ergebnis.Das sind Probleme, die ich sehen kann, ziemlich schnell.
Könnten Sie haben sich getrennt, aus den code-Blöcken, die sich mit arrays und hashes.
Ich würde empfehlen, beginnend aus Ihren Unterprogrammen wie diese, es sei denn, Sie haben einen wirklich guten Grund für eine andere Vorgehensweise.
( Wenn Sie es so machen dann Komodo, zumindest, wird in der Lage sein, um herauszufinden, was die Argumente sind auf Ihrer Unterroutine )
Gibt es nur selten Grund zum setzen einer variable in einen string enthält nur die variable.
Die einzige Zeit, die ich denke, würde ich es jemals tun wird, wenn ich mit einem Objekt, das hat eine überladene
""
Funktion, und ich möchte den string, ohne auch immer das Objekt.Ich kämpfte mit diesem problem vor, und fand meinen Weg hier. Ich fast eine Lösung hier gepostet, aber gefunden, eine passende ein (für mich jedenfalls). Lesen Sie über Tiefe Erste Rekursion hier.
Den sub im obigen Artikel funktioniert perfekt mit einem Referenz-mit anderen Hashes, Arrays oder Skalare. Es hat nicht-print-Hash-Schlüssel Namen, obwohl, so dass ich leicht modifiziert: