みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

Perlでのforeach文の挙動がわかりません

Perlに詳しい方教えてください。

WinXP(SP3)+ActivePerl-5.10.0.1004の環境で、重複データのチェックプログラムを
作成していますが、foreach文の挙動がよく分かりませんので教えてください。

※Perlは独学です。


<入力ファイル>
あいうえお
あいうえお
かきくけこ
あいうえお

<出力期待値その1>
あいうえお,重複しています
あいうえお,重複しています
かきくけこ
あいうえお,重複しています

<出力期待値その2>
あいうえお,重複しています
あいうえお,重複しています
かきくけこ
あいうえお


<プログラムの要約>

open(IN,$input_file); # 入力ファイルを読み込み
@BASE = <IN>;
close(IN);

@BASE_2 = @BASE ; # 配列のコピーを作成

$count_1 = '0' ;

foreach $data_1 (@BASE) {

  $count_1++ ; # 何行目を処理しているかのカウンター

  $flag_1 = '0' ; # フラグの初期化
  $count_2 = '0' ;

  foreach $data_2 (@BASE) { # ←★ここの記述方法の質問です★

    $count_2++ ;

    if ( $count_1 == $count_2 ) { next; } # 自分自身の行とは比較しない

    if ( $data_1 eq $data_2 ) { $flag_1 = '1' ; } # 一致したらフラグを立てる

  }
  
  if ( $flag_1 == '0' ) { # フラグが立たなかったらそのまま新しい配列へ追加

    push(@kekka,$data_1);

  } else { # フラグが立ったらコメントを追加して新しい配列へ

    $data_1 =~ s/\n//g;
    $data_3 = $data_1 . ",重複しています\n" ;
    push(@kekka,$data_3);

  }

}

$kekka_2 = join("",@kekka) ; # 配列のデリミタ対策

open(OUT,"> $output_file");
print OUT "$kekka_2";
close(OUT);

exit;


<質問>

上記プログラムの★マークの箇所で、

foreach $data_2 (@BASE_2) としますと、<出力期待値その1>が得られます

そして、

foreach $data_2 (@BASE) としますと、<出力期待値その2>が得られます


プログラムの途中で @BASE_2 = @BASE としていますので、一見しますと
同じ処理をしているように感じるのですけれども、実際には出力結果が異なり
ますので、何かが違うのだと思います。

その違いを教えて戴きたいです。


※投稿確認画面でTABが消えてしまいますのでTABは全角スペースに変更して
 おります。
 見えづらい場合には申し訳ありません

投稿日時 - 2011-05-13 18:16:49

QNo.6735002

困ってます

質問者が選んだベストアンサー

foreach文はオリジナルを置き換えますので注意して使ってください。

>$data_1 =~ s/\n//g;
# オリジナル(@BASE)の対象データが書き換えられる。

投稿日時 - 2011-05-13 18:38:34

お礼

ありがとうございます

最初は

あいうえお<改行コード>
あいうえお<改行コード>
かきくけこ<改行コード>
あいうえお<改行コード>

でしたけれども、foreachの最後では

あいうえお
あいうえお
かきくけこ<改行コード>
あいうえお<改行コード>

となっていて、どのデータとも重複しないのですね

難しいです

投稿日時 - 2011-05-13 19:44:49

ANo.1

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(1)

あなたにオススメの質問