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]がトークンです。

次のような 2 つの 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

ハッシュを反復処理し、すべてのキーを個別にテストして、それらの 1 つがターゲット値であるかどうかを確認している場合、ハッシュの機能であるルックアップを利用していません。次のようなものを試してください

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

代わりは。

于 2013-02-26T18:14:14.937 に答える