ループ中にリアルタイムでPerlに重複項目が出力されるのを防ぐ最良の方法

StackOverflow https://stackoverflow.com/questions/820423

  •  03-07-2019
  •  | 
  •  

質問

多くの「関連する」質問が表示されますが、この特定のシナリオに答えるのを見たものはありません。

SQL SELECTステートメントから生成された結果セットを解析するwhile / forループ中に、前の行に同じフィールドデータが含まれている場合(最初の行かどうか)、次の行が出力されないようにする最善の方法フィールドまたはx番目のフィールド)?

たとえば、2つの行が次の場合:

('EML-E','jsmith@mail.com','John','Smith')
('EML-E','jsmith2@mail.com','John','Smith')

「EML-E」が両方の行で同じであるという事実に基づいて、最初の行のみを印刷する最良の方法は何ですか?

今、私はこれをやっています:

  • 最初のフィールド(私のシナリオに固有)を2要素配列(dupecatch [1])に保存する
  • dupecatch [0] = dupcatch [1]であるかどうかの確認(複製-'s'を使用したエスケープループ)
  • 行の処理後、dupecatch [0] = dupecatch [1]を設定します

    while ($DBS->SQLFetch() == *PLibdata::RET_OK)
    {
        $s=0; #s = 1 to escape out of inside loop
        while ($i != $array_len and $s==0)
        {
            $rowfetch = $DBS->{Row}->GetCharValue($array_col[$i]);
            if($i==0){$dupecatch[1] = $rowfetch;} #dupecatch prevents duplicate primary key field entries
            if($dupecatch[0] ne $dupecatch[1])
            {
                dosomething($rowfetch);
            }
            else{$s++;}
            $i++;
        }
        $i=0;
        $dupecatch[0]=$dupecatch[1];
    }
    
役に立ちましたか?

解決

これは、行の重複項目だけを気にする場合の標準的な方法ですが、$ dupecatch [0]は通常$ old、$ dupecatch [1]は通常問題の変数という名前です。インデックスを参照するだけなので、配列が適切でないことがわかります。

すべての重複を避けたい場合は、%seenハッシュを使用できます:

my %seen;
while (defined (my $row = get_data())) {
    next if $seen{$row->[0]}++; #skip all but the first instance of the key
    do_stuff();
}

他のヒント

SQLステートメントでDISTINCTを使用することをお勧めします。これがおそらく最も簡単な修正方法です。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top