我无法理解以下Perl代码

时间:2013-09-08 05:09:39

标签: perl

我有以下Perl代码。

#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;

my @array = (  3, 4, 1, 4, 7, 7, 4, 1, 3, 8 );
my %unordered;
@unordered{@array} = undef;

foreach my $key (keys %unordered) {
print "Unordered: $key\n";
}

my %seen;
my @ordered;

foreach my $element (@array) {
  if (  not $seen{$element}++ ) {
    push @ordered, $element;
  }
}

在最后一个foreach代码块中,我无法理解这一点 - 在第一次迭代中,表达式not $seen{$element}++求值为0 - true - 所以if块执行。在第二次迭代中,表达式not $seen{$element}++应该再次计算为不为0 - 因为哈希是空的。因此,读取标量$seen{$element}将读取0而不是0将评估为true。因此,if块应该再次执行。但是,这本书说它在第一次迭代后停止了。谁能解释一下呢?

2 个答案:

答案 0 :(得分:2)

在第二次迭代中,哈希将不再为空,因为++运算符将在其中放置1。在第三次迭代中,值为2(为了此程序的目的与1相同,它只是意味着“至少看过一次”)。

在您的计划结束时,%seen将包含每个条目在您的列表中显示的次数。

if $a++增加$a的值(如果丢失则将其视为0),然后将该增量之前的值返回到比较。

使用后缀运算符很重要,因为if ++$a在这里不起作用:它还在哈希中放置1,但它返回修改的值(所以1即使是第一次迭代也是如此。

答案 1 :(得分:0)

最后一个foreach循环可以详细说明:

# loop on all elements of the array
foreach my $element (@array) {
    # if the current element haven't been seen yet
    if ( not exists $seen{$element} ) {
        # add current element into ordered array
        push @ordered, $element;
    }
    # Increment the number of time element have been seen
    $seen{$element}++;
}

最后,@ordered将包含:

(3, 4, 1, 7, 8)

更好的名称应该是@unique而不是@ordered

%seen将包含:

(3 => 2, 4 => 3, 1 => 2, 7 => 2, 8 => 1)