我在使用从数组派生的哈希时遇到了一些麻烦。它失败了#34;存在"测试我知道的那些元素。我写了一些小测试代码来证实这一点。这是:
#!/usr/local/bin/perl
my @sieve = (2, 3, 5, 7, 11, 13, 17, 19);
my %sieve_hash = @sieve;
foreach $prime (@sieve) {
if (exists($sieve_hash{$prime})) {
print "$prime exists!\n";
} else {
print "$prime DOES NOT exist.\n";
}
}
以下是示例输出:
2 exists!
3 DOES NOT exist.
5 exists!
7 DOES NOT exist.
11 exists!
13 DOES NOT exist.
17 exists!
19 DOES NOT exist.
我做错了什么?
答案 0 :(得分:8)
分配哈希时,需要一个交替键和值列表。以下将解决您的问题:
my %sieve_hash = map { $_ => 1 } @sieve;
通过上述内容,简单的真值测试(而不是存在测试)就足够了。但是,由于您正在使用存在测试,因此可以使用以下内容分配undef
而不是1
来节省一些内存:
my %sieve_hash;
@sieve_hash{ @sieve } = ();
或
my %sieve_hash;
$sieve_hash{$_} = undef for @sieve;
但是,我发现真相测试更加优雅。
答案 1 :(得分:1)
将数组分配给散列时,偶数索引元素,例如$ sieve [0],$ sieve [2]成为哈希键,奇数元素$ sieve [1],$ sieve [3]等成为哈希值。您会注意到输出中的模式,其中只有每个其他元素(第0,第2,第4)“存在”作为哈希中的键。
使用Data :: Dumper查看发生了什么:
#!/usr/bin/perl
use Data::Dumper;
my @sieve = (2, 3, 5, 7, 11, 13, 17, 19);
my %sieve_hash = @sieve;
print STDERR "Your array:\n";
print Dumper \@sieve;
print STDERR "Your hash:\n";
print Dumper \%sieve_hash;
Your array:
$VAR1 = [
2,
3,
5,
7,
11,
13,
17,
19
];
Your hash:
$VAR1 = {
'11' => 13,
'17' => 19,
'2' => 3,
'5' => 7
};
答案 2 :(得分:0)
当你说
时my %sieve_hash = @sieve;
它将数组的每个其他元素作为一个键,其他元素作为值。
因此,您的哈希看起来与从以下构造的哈希相同:
my %sieve_hash = (
2 => 3,
5 => 7,
... and so on
);