Comment passer de хешу en Perl

De la tâche. Dans le code Perl programme un hachage %h. Dans ce hachage avez des paires de valeurs. Vous devez passer par tous les éléments de hachage et suivre les étapes de chaque élément.

Marcher sur хешу avec l'aide de foreach

Le plus souvent, le moyen le plus pratique pour contourner le hachage est d'utiliser foreach. Voici un exemple de code:

▶ Run
#!/usr/bin/perl

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

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

C'est tout assez simple. Tout d'abord, nous créons de hachage %h dans lequel il ya trois paires de valeurs. Plus loin se trouve le cycle. Avec l'aide de keys %h , nous avons reçu la liste de toutes les clés de hachage (dans cet exemple, les lignes 'a', 'b' et 'asdf'). La chaîne avec la clé est placée dans la variable $key et fait le corps de la boucle, puis $key placé la clé de hachage et de nouveau fait le corps de la boucle, et cela se produit pour toutes les clés.

Si vous enregistrez ce code dans un fichier script.pl et de l'exécuter perl script.pl, puis l'écran s'affiche l'ensemble des paires de valeurs qui figurent dans le hachage:

b - 20
asdf - Hello
a - 1

Le hachage est une un ensemble de paires de valeurs. Et la conclusion c'est bien visible — l'ordre dans lequel ont été retirés les éléments de hachage ne correspondent pas l'ordre dans lequel elles ont été définies dans le code du programme. Et si vous l'exécutez ce script plusieurs fois, l'ordre des éléments dans la sortie va changer. keys %h retourne la liste des clés hachage dans un ordre aléatoire. Si vous souhaitez que l'ordre était toujours le même, pour cela, par exemple, vous pouvez utiliser le tri foreach my $key (sort keys %h) {.

Passer par хешу à l'aide de while et each

Une autre méthode pour contourner tout le hachage est d'utiliser une boucle while et le mot-clé each. Voici le code qui fonctionne aussi bien que pour l'exemple précédent:

▶ Run
#!/usr/bin/perl

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

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

each %h renvoie une liste de deux éléments — clé de hachage et la même valeur. Exactement la même que en cas de keys de l'ordre dans lequel each retourne une paire de valeurs n'est pas défini. Les différents lancements de la même le programme va renvoyer une paire de différents ordres.

Nous attribuons de la valeur qui a renvoyé each dans des variables. each se souvient les paires de hachage, il est déjà posé et lors de la prochaine utilisation renverra une autre paire de valeurs. Il se poursuivra jusqu'à ce que each ne reviendra pas à tous les couples, après cela, il retourne une liste vide. Jusqu'à ce que each renvoie une paire de valeurs se fait corps while du cycle, une fois qu'il retourne une liste vide le cycle de whilese termine.

Modification des valeurs dans le hachage

Lors de l'utilisation de foreach du cycle, keys %h se fait qu'une seule fois. Lors de l'utilisation de whiledu cycle each se fait lors de chaque itération.

Étendre la tâche précédente — nous avons besoin non seulement d'afficher tous les éléments de hachage, mais encore de les remplacer. C'est tout à fait sans problème, vous pouvez faire lorsque vous utilisez foreach et 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;

La sortie du programme:

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

Mais cela ne peut pas se faire avec 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;

Lorsque vous exécutez ce programme, l'écran affiche quelque chose comme:

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 a renvoyé une paire de valeurs de hachage, puis nous changeons de hachage. Se passe la prochaine itération de la boucle et eachrenvoie une paire de modifié de hachage et il peut très bien ramener la paire, qui vient d'être ajoutée.

Donc, si lors de l'analyse de hachage besoin de le changer, alors vous devez utiliser foreach et keys. Lors de l'utilisation while et each le programme ne fonctionnera pas correctement.

Thèmes connexes

Autres articles