2013-02-26 71 views
2

我上週開始學習Perl。比較兩個關聯數組

我有一個包含'令牌'的文件的關聯數組 - 只是一堆數字。 我有一個SQL數據庫中包含'令牌'的另一個關聯數組。

我想看看文件中的任何標記是否不在數據庫中。然而,我所做的任何事似乎都不起作用,而我得出的結論是我只是迷惑自己。

我不知道我完全理解關聯數組還沒有,但這是我的代碼,文件哈希的一個片段:

while($row = <FILE>){ 
    if($row =~ /^000\E/){ 
     @tmp=split(/\s+/,$row);  
     if($tmp[1] ne "Unassigned"){ 
      $tokenfile{$tmp[0]} = $tmp[1] . " " . $tmp[2]; 
     } 
    } 
} 

$tmp[1] + $tmp[2]是第一和第二的名字。我後來比較名稱,看他們是否相等。不過,我想比較$tmp[0] - 令牌。這是SQL哈希:

while(@rows = $sth->fetchrow_array){ 
    ($name, $passwd, $uid, $gid, $quota, $comment, $gcos, $dir, $shell) = getpwnam("\L$rows[1]\E"); 
    $gcos =~ s/,.*//; 
    if(!defined($gcos)){ 
     $missing++; 
     $tokendb{$rows[0]} = $rows[1]; 
    } 
    else{ 
     $tokendb{$rows[0]} = $gcos; 
    } 
} 

$rows[0]是令牌。

我以爲我會使用兩個foreach循環像這樣:

foreach $token (keys(%tokendb)) { 
    foreach $token2(keys(%tokenfile)){ 
     if($token ne $token2){ 
      print "$token2 NOT IN DATABASE\n"; 
     } 
    } 
} 

但是,讓我仍然在數據庫中值的很多的結果。

我想知道爲什麼這不起作用的一些提示。非常令人沮喪,因爲我知道這很簡單,但是我的大腦今天工作得並不好(儘管這是我的第21個生日:|)。

+0

'/^000 \ E /'中的'\ E'應該表示什麼?該轉義序列用於終止其他轉義序列,如'\ Q ... \ E'。 – TLP 2013-02-26 17:39:32

+0

請嘗試此操作調試目的'使用Data :: Dumper; $ Data :: Dumper :: Useqq = 1;打印Dumper \%tokendb,\%tokenfile;'。或者如果這太亂了,打印循環中的值:'print Dumper''$ token'ne'$ token2'「' – TLP 2013-02-26 17:45:11

+1

警告!警告!如果你從一個仍然調用哈希「關聯數組」的源代碼學習Perl,那麼你正在從一個可能超過十五年過時的源學習。 – 2013-02-27 09:31:15

回答

1

如果您正在迭代散列並單獨測試每個鍵以查看其中一個鍵是否是目標值,那麼您沒有利用散列的強大功能:查找。嘗試類似

foreach $token (keys(%tokenfile)) { 
    unless (exists $tokendb{$token}) { 
    print "$token NOT IN DATABASE\n"; 
    } 
} 

改爲。

3
foreach $token (keys(%tokenfile)) { 
    if (! exists $tokendb{$token}) { 
    print "$token NOT IN DATABASE\n"; 
    } 
} 

您的嵌套循環失敗,因爲即使一個鍵存在,它不匹配所有其他鍵。爲了嵌套循環做到這一點,它應該是:

foreach $token (keys(%tokenfile)) { 
    $found = 0; 
    foreach $token2 (keys(%tokendb)) { 
    if ($token eq $token2) { 
     $found = 1; 
     last; 
    } 
    } 
    if (!found) { 
    print "$token NOT IN DATABASE\n"; 
    } 
} 

當然,沒有理由把它這樣寫的,這只是幫助你瞭解你的邏輯是如何失敗。

+1

您應該指出,在這種情況下循環散列鍵是多餘的。另外,我假設你的意思是'$ found'和'last',而不是'found'和'break'。 – TLP 2013-02-26 18:06:10

+0

謝謝 - 最近太多的PHP/Javascript .... – Barmar 2013-02-26 18:08:04

+0

不客氣。 – TLP 2013-02-26 18:08:28