比较两个关联数组

时间:2013-02-26 17:31:33

标签: arrays perl hash comparison associative

我上周开始学习Perl。

我有一个包含'tokens'的文件的关联数组 - 只是一堆数字。 我有一个包含'tokens'的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";
        }
    }
}

但是这给了我仍然在数据库中的 lot 值的结果。

我喜欢一些提示,说明为什么这不起作用。非常令人沮丧,因为我知道这很简单,但我的大脑今天工作得不好(即使这是我的第21个生日:|)。

2 个答案:

答案 0 :(得分: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 :(得分:1)

如果你正在迭代一个哈希并单独测试每个键以查看其中一个是否是目标值,那么你就不会利用哈希的力量:查找。尝试像

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

代替。