電子書籍の厳選無料作品が豊富!

以下のようなデータ(CSV)があったとします。

1020,大森,3249
1023,高橋,3252
1020,大森,3249


ここで1020が重複しているので重複させないように
printしたいと考えています。ほかにも多数のデータ
が重複しているかも知れない。

本を見て、ハッシュのキーは重複しない
ことを利用して

foreach (@man){
$H{$_}=1; #値は無視しキーにセット
}

@man = keys %H;  #ハッシュキーを配列へ

foreach $eachman (@man) {
($num, $name, $encpass) = split(/,/, $eachman);

print ・・・・
・・・・

のように作ってみましたが、重複されて
表示されます。順番のみ変わっていました。

このような感じで簡単にできる方法がありましたら
教えてください。

A 回答 (4件)

質問を勘違いしているかもしれませんが、%H or %tmpを活かせばもっとシンプルになると思います。



my %tmp;
while (<DATA>) {
  chomp;
  my ($num, $name, $encpass) = split /,/;
  if (!$tmp{$num}++) {
    print "$num:$name\n";
  }
}
__END__
1020,大森,3249
1021,塚本,3250
1022,播磨,3251
1023,高橋,3252
1024,周防,3253
1025,沢近,3254
1023,高橋,3252
1020,大森,3249
1023,高橋,3252
1024,周防,3253

参考URL:http://www.meibin.net/reference/books/perl2/cook …
    • good
    • 0
この回答へのお礼

回答ありがとうございました。

while (<DATA>) を使う方法ですが、どうして止まるか原因がわかりました。

別ルーチンでopen TXT 、・・・みたいなことをやって配列にTXTの内容を入れてしまっています。

while(<>)<>の部分が配列ではダメなんですよね?試してみましたがダメでした。

お礼日時:2006/09/01 00:26

> while(<>)<>の部分が配列ではダメなんですよね?試してみましたがダメでした。



配列に対してその要素を列挙しつつ操作をするのなら
for $var (@arrary) または foreach $var (@array)
を使います。
$var は省略できて、その場合は $_ で各要素が参照できます。

あと念のため解説しておきますが、DATAというファイルハンドルは
openしないでも使うことができて、どこからデータを持ってくるのかというと、
スクリプトの末尾、__END__の後におかれた行です。
    • good
    • 0
この回答へのお礼

回答ありがとうございました。

理解しようと試みましたが、ダメでしたので締め切ることにしました。パールって奥が深いですね。

お礼日時:2006/09/03 22:21

> whileの文があると途中で処理が終わっちゃうみたいでHTMLが最後まで表示されない現象が起こりました。



これはなにやらよくわかりませんが、

> ただ、データが完全一致していないと重複チェックが消えないようで、
> 1列目をキーにできればいいのですが、その方法はあるでしょうか?

ということであれば、

foreach (@man){
 $H{$_}=1;
}

このループを
foreach (@man){
 my $num;
 ($num, undef) = split(/,/, $_, 2);
 $H{$num}=$_;
}

としてやって、

foreach $eachman (sort keys %H) {
 ($num, $name, $encpass) = split(/,/, $H{$eachman});

でどうでしょう?
この場合先頭のエントリが同じものは最後に登場したものが有効になります。

2回同じ文字でsplitするのはいやらしいですが、わかりやすさを優先ということで。
    • good
    • 0
この回答へのお礼

回答ありがとうございました。

おかげさまで出来ました。2回Splitするのは改善できればいいですけど、私には無理そうですが、勉強してみます。

お礼日時:2006/09/01 00:24

基本的な考え方は間違ってはいないと思います。


試しに提示されたコード片を元にスクリプトを組んでみましたが正しく動いています。

ハッシュにためたデータを配列に書き戻してますけど、
似たような別の名前の変数に入れちゃってるなんてことは
ありませんか?

use strict;
use warnings;

my %tmp;
my @table;

while (<DATA>) {
  chomp;
  push @table, $_;
}

foreach (@table){
  $tmp{$_} = 1;
}

foreach my $entry (sort keys %tmp) {
  my ($num, $name, $encpass) = split(/,/, $entry, 3);

  print "$num:$name\n";
}
__END__
1020,大森,3249
1021,塚本,3250
1022,播磨,3251
1023,高橋,3252
1024,周防,3253
1025,沢近,3254
1023,高橋,3252
1020,大森,3249
1023,高橋,3252
1024,周防,3253

実行結果:
1020:大森
1021:塚本
1022:播磨
1023:高橋
1024:周防
1025:沢近

この回答への補足

回答ありがとうございました。

書かれてあるとおりやってみると、

whileの文があると途中で処理が終わっちゃうみたいでHTMLが最後まで表示されない現象が起こりました。

で、こんな感じで組んでみたんですけど

#while (@man) {
#chomp;
#push @table, $_;
#}

foreach (@man){
$H{$_}=1;
}

#@table = keys %H;

foreach $eachman (sort keys %H) {
($num, $name, $encpass) = split(/,/, $eachman);


近いところまでいきました。
ただ、データが完全一致していないと重複チェックが消えないようで、1列目をキーにできればいいのですが、その方法はあるでしょうか?

実はデータは、
1020,大森,3249,5,8,0,,,,,

みたいに後ろが続いてまして申し遅れましたm(__)m

補足日時:2006/08/30 14:51
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!