Bagaimana untuk lulus hash di Perl

Tugas. Dalam kode program Perl ada hash %h. Di hash ini ada beberapa pasang nilai. Anda perlu untuk pergi melalui semua hash item dan melakukan tindakan dengan masing-masing item.

Berjalan melalui hash menggunakan foreach

Paling sering, cara yang paling mudah untuk memotong hash adalah dengan menggunakan foreach. Berikut adalah contoh kode:

▶ Run
#!/usr/bin/perl

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

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

Itu semua cukup sederhana. Pertama kita membuat sebuah hash %h yang memiliki tiga pasang nilai. Berikutnya adalah sebuah siklus. Menggunakan keys %h kita mendapatkan suatu daftar dari semua hash kunci (dalam contoh ini, baris 'a', 'b' dan 'asdf'). Kata kunci yang ditulis ke dalam sebuah variabel $key , dan mengeksekusi loop tubuh, kemudian di $key cocok berikut hash key dan lagi-lagi mengeksekusi loop tubuh, dan ini terjadi untuk semua tombol.

Jika anda menyimpan kode ini ke file script.pl dan menjalankannya perl script.pl, maka layar akan muncul sebuah himpunan pasangan dari nilai-nilai yang terkandung dalam hash:

b - 20
asdf - Hello
a - 1

Hash adalah unordered set nilai-nilai. Dan kesimpulan ini terlihat jelas — urutan di mana ia ditarik elemen-elemen hash tidak sesuai dengan urutan di mana mereka didefinisikan dalam kode program. Dan jika anda menjalankan script ini beberapa kali, urutan unsur-unsur dalam output akan berubah. keys %h kembali daftar kunci hash dalam urutan yang sewenang-wenang. Jika anda perlu untuk urutan yang selalu sama, misalnya, anda dapat menggunakan sorting foreach my $key (sort keys %h) {.

Lulus hash menggunakan while dan each

Cara lain untuk menghindari seluruh hash adalah dengan menggunakan loop while dan kata kunci each. Berikut ini adalah kode yang bekerja sama dengan contoh sebelumnya:

▶ Run
#!/usr/bin/perl

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

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

each %h menghasilkan sebuah daftar dari dua elemen — hash kunci dan nilai yang sesuai. Persis sama seperti dalam kasus keys urutan di mana each pasang kembali nilai-nilai yang tidak didefinisikan. Berbeda berjalan yang sama program ini akan mengembalikan pasangan dalam urutan yang berbeda.

Kami menetapkan nilai-nilai yang dikembalikan each dalam variabel-variabel. each mengingat yang pasang hash ia diberi waktu berikutnya anda menggunakan kembali nilai yang berbeda pasangan. Ini akan berlanjut sampai each tidak kembali semua pasangan, maka itu akan kembali daftar kosong. Sementara each kembali beberapa nilai-nilai, mengeksekusi tubuh while siklus, setelah itu kembali kosong daftar siklus whileselesai.

Mengubah nilai hash

Ketika menggunakan foreach siklus keys %h dieksekusi hanya sekali. Ketika menggunakan whilesiklus each dilakukan pada setiap iterasi.

Memperpanjang masalah sebelumnya — kita tidak hanya perlu untuk menampilkan semua elemen-elemen hash, tetapi juga untuk menggantikan mereka. Hal ini benar-benar tidak ada masalah ketika menggunakan foreach dan 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;

Output dari program ini:

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

Ini tidak bekerja untuk membuat ketika menggunakan 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;

Ketika anda menjalankan program ini pada layar akan muncul sesuatu seperti:

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 kembali nilai pasangan dari hash, dan kemudian kita mengubah hash. Adalah sebagai berikut iterasi dari loop dan eachkembali beberapa modifikasi hash, dan dapat mengembalikan pasangan yang baru saja ditambahkan.

Jadi jika bypass hash perlu untuk mengubah itu, anda perlu menggunakan foreach dan keys. Ketika menggunakan while dan each program tidak akan bekerja dengan benar.

Topik terkait

Artikel lainnya