Wie man auf хешу in Perl

Aufgabe. Im Code Perl Programm ein Hash %h. In diesem хеше es gibt einige Wertepaare. Müssen gehen durch alle Elemente der Hash-Wert und führen Sie die Schritte für jedes Element.

Gehen Sie durch хешу mit foreach

Am häufigsten, die einfachste Methode, um den Hash zu umgehen ist die Verwendung foreach. Hier ist der Beispielcode:

▶ Run
#!/usr/bin/perl

my %h = (
    a => 1,
    b => 20,
    asdf => 'Hello',
);

foreach my $key (keys %h) {
    print "$key - $h{$key}\n";
}

Hier ist alles ganz einfach. Zuerst legen wir eine Hash %h in dem es drei Wertepaare. Weiter ist der Zyklus. Mit Hilfe keys %h erhielten wir eine Liste mit allen Schlüsseln Hash (in diesem Beispiel Zeile 'a', 'b' und 'asdf'). Die Zeile mit Schlüssel wird in die Variable $key und Körper der Schleife ausgeführt wird, dann in $key passt die folgende Hash-Schlüssel und wieder wird der Körper Zyklus, und so ist es für alle Schlüssel.

Wenn der Code gespeichert in einer Datei script.pl und führen Sie es perl script.pl, das auf dem Bildschirm erscheint eine Reihe von Wertepaaren, die in хеше:

b - 20
asdf - Hello
a - 1

Hash ist eine ungeordnete Reihe von Wertepaaren. Und zum Schluss ist es gut zu sehen — die Reihenfolge in der die gezüchtet wurden die Elemente der Hash-Wert nicht gleich mit der Reihenfolge in der Sie definiert wurden, im Code des Programms. Und wenn Sie laufen dieses Skript ein paar mal, dann ist die Reihenfolge der Elemente in der Ausgabe variieren. keys %h gibt die Liste der Schlüssel Hash in beliebiger Reihenfolge. Wenn Sie brauchen, um die Reihenfolge war immer gleich ist, ist das für dieses Beispiel verwendet werden können, Sortierung foreach my $key (sort keys %h) {.

Pass auf хешу mit while und each

Ein anderer Weg, um zu umgehen das gesamte Hash — Zyklus ist zu verwenden while und das Schlüsselwort each. Hier ist der Code, das funktioniert genauso wie das Vorherige Beispiel:

▶ Run
#!/usr/bin/perl

my %h = (
    a => 1,
    b => 20,
    asdf => 'Hello',
);

while (my ($key, $value) = each %h) {
    print "$key - $value\n";
}

each %h liefert eine Liste aus zwei Elementen — Hash-Schlüssel und den dazugehörigen Wert. Genauso wie im Falle keys die Reihenfolge, in welcher each gibt die Wertepaare nicht definiert. Verschiedene Starts derselben Programm zurückgegeben werden Paare in unterschiedlicher Reihenfolge.

Wir weisen die Werte der zurückzusendenden each in der Variablen. each erinnert, welche Hash Paare gab es bereits und bei der nächsten Verwendung wieder andere Wertepaare. So wird es weitergehen bis each nicht wieder alle Paare, danach hat er eine leere Liste zurück. Während each gibt Wertepaar wird der Körper while - Zyklus, sobald er eine leere Liste zurückgegeben, Zyklus whilebeendet.

Eine änderung der Werte in хеше

Bei der Verwendung foreach - Zyklus, keys %h nur einmal ausgeführt. Bei der Verwendung whileZyklus each wird bei jeder Iteration.

Erweitern Sie die Vorherige Aufgabe — wir müssen nicht alle Elemente angezeigt werden nur Hash, sondern auch ersetzen. Es ist völlig ohne Probleme können bei der Verwendung foreach und keys:

▶ Run
#!/usr/bin/perl

use Data::Dumper;

my %h = (
    a => 1,
    b => 20,
    asdf => 'Hello',
);

foreach my $key (keys %h) {
    print "$key - $h{$key}\n";
    $h{ $key . $key } = $h{$key};
    delete $h{$key};
}

print Dumper \%h;

Ausgabe des Programms:

asdf - Hello
a - 1
b - 20
$VAR1 = {
          'bb' => 20,
          'aa' => 1,
          'asdfasdf' => 'Hello'
        };

So läuft das aber nicht tun, wenn die each:

▶ Run
#!/usr/bin/perl

use Data::Dumper;

my %h = (
    a => 1,
    b => 20,
    asdf => 'Hello',
);

while (my ($key, $value) = each %h) {
    print "$key - $value\n";

    # error!
    $h{ $key . $key } = $value;
    delete $h{$key};
}

print Dumper \%h;

Beim starten dieses Programms erscheint auf dem Bildschirm so etwas wie:

Use of each() on hash after insertion without resetting hash iterator results in undefined behavior at script.pl line 11.
Use of each() on hash after insertion without resetting hash iterator results in undefined behavior at script.pl line 11.
Use of each() on hash after insertion without resetting hash iterator results in undefined behavior at script.pl line 11.
Use of each() on hash after insertion without resetting hash iterator results in undefined behavior at script.pl line 11.
b - 20
bb - 20
bbbb - 20
asdf - Hello
$VAR1 = {
          'asdfasdf' => 'Hello',
          'bbbbbbbb' => 20,
          'a' => 1
        };

each gab ein paar Werte aus dem Hash, und dann ändern wir den Hash. Kommt die nächste Iteration des Zyklus und eachgibt ein paar der geänderten Hash-Wert und er kann auch wieder das paar, das gerade kam.

Also, wenn beim durchforsten von Hash Code ändern können, dann müssen Sie verwenden foreach und keys. Bei der Verwendung while und each das Programm wird nicht korrekt funktionieren.

Verwandte Themen

Andere Artikel