Làm thế nào để vượt qua một băm Perl

Nhiệm vụ. Trong mã của Perl chương trình đó là một băm %h. Trong này băm có một số cặp giá trị. Anh cần phải đi qua tất cả các băm mục và thực hiện hành động với mỗi mục.

Đi qua băm sử dụng foreach

Thông thường, một cách thuận tiện nhất để vượt qua những băm là để sử dụng foreach. Đây là một ví dụ mã:

▶ Run
#!/usr/bin/perl

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

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

Nó hoàn toàn đơn giản. Đầu tiên, chúng tôi tạo ra một băm %h trong đó có ba cặp giá trị. Tiếp theo là một chu kỳ. Bằng cách sử dụng keys %h , chúng tôi thu được một danh sách của tất cả các băm tên (trong ví dụ này, dòng 'a', 'b''asdf'). Chìa khóa chuỗi được viết vào một biến $key , và thực hiện các vòng cơ thể, sau đó trong $key phù hợp với sau băm chìa khóa và một lần nữa thực hiện những vòng lặp cơ thể, và điều này sẽ xảy ra cho tất cả các phím.

Nếu bạn tiết kiệm mã này như một tập tin script.pl và chạy nó perl script.pl, sau đó màn hình này sẽ xuất hiện một thiết của cặp giá trị chứa trong băm:

b - 20
asdf - Hello
a - 1

Một băm là một cách có thứ tự bộ giá trị. Và kết luận là rõ ràng — trật tự, trong đó nó đã bị thu hồi các yếu tố của băm không phù hợp với các thứ mà họ đã được xác định trong chương trình mật mã. Và nếu bạn chạy kịch bản này nhiều lần thứ tự của các yếu tố trong các sản sẽ thay đổi. keys %h trở lại danh sách các phím băm trong một trật tự tùy ý. Nếu bạn cần để đặt hàng đã luôn luôn cùng một ví dụ, bạn có thể sử dụng phân loại foreach my $key (sort keys %h) {.

Vượt qua băm sử dụng whileeach

Một cách để phá vỡ toàn bộ băm là để sử dụng một vòng while và chìa khóa từ each. Đây là mã mà làm việc tương tự như vậy để ví dụ:

▶ Run
#!/usr/bin/perl

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

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

each %h trở lại một danh sách của hai yếu tố — một băm chìa khóa tương ứng của nó giá trị. Chính xác là giống như trong trường hợp keys thứ tự trong đó each trở về cặp giá trị là không được xác định. Chạy khác nhau cùng chương trình sẽ trở lại các cặp trong đơn đặt hàng khác nhau.

Chúng tôi chỉ định các giá trị đó có trở về each trong biến. each nhớ mà cặp của băm ông đã được đưa ra tiếp theo thời gian, bạn sử dụng trả một giá trị khác nhau cặp. Điều này sẽ tiếp tục cho đến khi each không trả lại tất cả các cặp đó, sau đó nó sẽ trở lại một danh sách rỗng. Trong khi each trở về một vài giá trị thực cơ thể của while chu kỳ, một khi nó trở về một danh sách rỗng chu kỳ whileđược hoàn thành.

Thay đổi giá trị trong băm

Khi sử dụng foreach chu kỳ keys %h được thực hiện chỉ một lần. Khi sử dụng whilevòng each được thực hiện ở mỗi lần lặp.

Mở rộng các vấn đề trước đó — chúng ta không cần phải chỉ để hiển thị tất cả các yếu tố của băm, nhưng cũng phải thay thế họ. Nó là hoàn toàn không có vấn đề khi sử dụng foreachkeys:

▶ 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;

Đầu của chương trình này:

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

Nó không làm việc để làm khi sử dụng 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;

Khi bạn chạy chương trình này trên màn hình này sẽ xuất hiện một cái gì đó như là:

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 trở về giá trị cặp từ băm, và sau đó chúng ta sẽ thay đổi băm. Là sau lần lặp và eachtrở lại một vài thay đổi băm, và nó có thể trở về những cặp bạn chỉ cần thêm.

Vì vậy, nếu các bỏ qua băm cần phải thay đổi nó, bạn phải sử dụng foreachkeys. Khi sử dụng whileeach chương trình sẽ không làm việc một cách chính xác.

Chủ đề liên quan

Các bài viết khác