2013-02-26 66 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