2013-05-16 44 views
2

我在使用從數組派生的哈希時遇到了一些問題。它沒有「存在」測試我知道那裏的元素。我寫了小測試代碼來證實這一點。那就是:從陣列派生的perl哈希無法按預期方式工作

#!/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. 

我在做什麼錯?

回答

8

當分配給散列值時,預計會出現交替鍵和值的列表。以下內容將解決您的問題:

my %sieve_hash = map { $_ => 1 } @sieve; 

通過上述,簡單的真相測試(而不是存在測試)就足夠了。但是,由於您使用的是存在測試,您可以通過使用以下節省一些內存分配undef,而不是1

my %sieve_hash; 
@sieve_hash{ @sieve } =(); 

my %sieve_hash; 
$sieve_hash{$_} = undef for @sieve; 

我找到了一個道理測試更優雅,雖然。

+0

感謝。這解釋得非常好。 – Mandar

0

當你說

my %sieve_hash = @sieve; 

它以陣列作爲鍵,其他元素的值的每隔一個的元件。

所以你看的哈希一樣,如果它是從構建:

my %sieve_hash = (
    2 => 3, 
    5 => 7, 
    ... and so on 
); 
1

當你分配一個數組哈希,偶數索引元素,例如$ sieve [0],$ sieve [2]成爲散列鍵,奇數編號的元素$ sieve [1],$ sieve [3]等成爲散列值。您會注意到輸出中的模式,其中只有每個其他元素(第0,第2,第4)「存在」作爲散列中的鍵。

使用數據::自卸車,看看發生了什麼事情:

#!/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 
     };