我见过一个简单的程序。好吧,除了一件事,我理解的洞程序就是Hash在这里工作的方式:
程序 - >从列表中提取唯一元素
@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";
}
我的问题是哈希是如何从其现有价值与当前价值进行比较的,即它是如何检查天气的价值已经存在与否。如果我打印出看到的%,我会得到一些价值。那些价值来了吗?
答案 0 :(得分:2)
如果它让您更清楚,请更改
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;
答案 1 :(得分:1)
检查unless ($seen{$item})
探测密钥$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})
将不会成功,因此将跳过该项目。
答案 2 :(得分:0)
$seen{$item}
将是未定义的或数字。
$seen{$item}++;
会将其设为数字。