Hvordan til at passere en hash i Perl

Opgave. I koden for Perl-program, der er en hash %h. I denne hash-der er nogle par af værdier. Du er nødt til at gå igennem alle de hash-elementer og udføre handlinger med hvert element.

Gå gennem hash hjælp foreach

Oftest, er den mest bekvemme måde at omgå hash er at bruge foreach. Her er et eksempel kode:

▶ Run
#!/usr/bin/perl

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

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

Det hele er ganske simpelt. Først skal vi oprette en hash %h , som har tre par af værdier. Næste er en cyklus. Hjælp keys %h vi fået en liste af alle hash nøgler (i dette eksempel, line 'a', 'b' og 'asdf'). Nøglen string er skrevet ind i en variabel $key , og udfører loop kroppen, så i $key passer til følgende hash-nøgle og igen udfører loop kroppen, og det sker for alle nøgler.

Hvis du gemmer denne kode til en fil script.pl , og køre det perl script.pl, så skærmen vises et sæt af par af værdier indeholdt i hash:

b - 20
asdf - Hello
a - 1

Et hash er en uordnet sæt af værdier. Og konklusionen er klart synlig — den rækkefølge, i hvilken det blev trukket tilbage de elementer af hash, ikke svarer til den rækkefølge, som de blev defineret i det program kode. Og hvis du løber dette script flere gange, rækkefølgen af elementer i produktionen vil ændre sig. keys %h returnerer listen af nøgler hash i en vilkårlig rækkefølge. Hvis du har brug for at bestille var altid den samme, for eksempel, du kan bruge sortering foreach my $key (sort keys %h) {.

Pass hash hjælp while og each

En anden måde at omgå det hele hash er at bruge en løkke while , og de centrale ord each. Her er den kode som arbejder på samme måde som i det foregående eksempel:

▶ Run
#!/usr/bin/perl

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

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

each %h giver en liste med to elementer — en hash-tasten og den tilsvarende værdi. Præcis det samme som i tilfælde keys den rækkefølge, som each afkast par af værdier er ikke defineret. Forskellige kørsler af samme programmet vil returnere par i forskellige ordrer.

Vi tildele værdier, som er vendt tilbage each i variabler. each husker, hvilke par af hash han blev givet næste gang du bruger returnerer forskellige værdi-par. Dette vil fortsætte, indtil each ikke returnere alle de par, så vil det returnere en tom liste. Mens each returnerer et par af værdier, udfører kroppen af while cyklus, når den returnerer en tom liste cyklus whileer afsluttet.

Ændre værdier i hash

Når du bruger foreach cyklus keys %h udføres kun én gang. Når du bruger whilecyklus each er udført ved hver iteration.

Udvide det foregående problem — vi har brug for ikke kun at vise alle de elementer af hash, men også til at erstatte dem. Det er helt ikke noget problem, når du bruger foreach og 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;

Outputtet af programmet:

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

Det virker ikke til at gøre, når at bruge 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;

Når du kører dette program på skærmen vises noget lignende dette:

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 returnerede værdi-par fra hash, og så må vi ændre hash. Er den følgende iteration i løkken og eachvender tilbage et par af de ændrede hash, og det kan vende tilbage parret, at du lige har tilføjet.

Så hvis bypass-hash nødt til at ændre det, du er nødt til at bruge foreach og keys. Når du bruger while og each vil programmet ikke fungere korrekt.

Relaterede emner

Andre artikler