2

我看过一个简单的程序。好吧,除了一件事,我理解的洞程序就是哈希在这里的工作方式:

程序 -> 从列表中提取唯一元素

@list = (20,30,40,60,40,20,30,2);
@uniq = ();
%seen = ();
foreach $item (@list) {
    unless ($seen{$item}) 
    {
        # if we get here, we have not seen it before
        push(@uniq, $item);
        $seen{$item}++;

    }
    print %seen;
    print"\n";
}

我的问题是哈希如何从其现有值与当前值进行比较,即它如何检查天气该值是否已经存在。如果我正在打印 %seen 我得到了一些值。这些值是如何来的?

4

3 回答 3

3

如果它让您更清楚,请更改

if (!$seen{$item}) { $seen{$item}++; ... }

if (!exists($seen{$item})) { $seen{$item} = 1; ... }

第一次遇到特定项目时,它在哈希中不作为键存在,因此if输入了 。的主体if在哈希中创建一个与项目相等的键。

第二次(以及第三次和...)遇到特定项目时,它作为键存在于哈希中,因此if不输入。


顺便一提,

if (!$seen{$item}) { $seen{$item}++; ... }

可以缩短为

if (!$seen{$item}++) { ... }

my @uniq;
for my $item (@list) {
    push @uniq, $item if ...;
}

可以缩短为

my @uniq = grep ..., @list;

所以整个事情可以写成

my @list = (20,30,40,60,40,20,30,2);
my %seen;
my @uniq = grep !$seen{$_}++, @list;
于 2012-07-25T15:58:45.890 回答
1

检查unless ($seen{$item})会探测哈希表中的 key $item。如果看到密钥,则测试将失败,因为$seen{$item}它将被定义且非零。

如果哈希表中没有条目:

push(@uniq, $item);   # store this item
$seen{$item}++;       # and increment the value for this key in the hash table

未定义的值被认为是0,因此该语句$seen{$item}++将其值设为 1(您不妨将其写为$seen{$item} = 1.

如果在列表中再次遇到该项目,unless ($seen{$item})则不会成功,因此将被跳过。

于 2012-07-25T15:36:51.687 回答
0

$seen{$item}要么是未定义的,要么是一个数字。

$seen{$item}++;将使其成为一个数字。

于 2012-07-25T15:36:41.767 回答