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 岁生日:|)。

4

2 回答 2

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";
  }
}

当然,没有理由这样写,这只是为了帮助您了解您的逻辑是如何失败的。

于 2013-02-26T17:44:32.897 回答
1

如果您要遍历散列并单独测试每个键以查看其中一个是否为目标值,那么您就没有利用散列的强大功能:查找。尝试类似的东西

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

反而。

于 2013-02-26T18:14:14.937 回答