• 締切済み

CSVデータの編集の際の重複チェックの方法

今、data.csv(カンマ区切り)として、左から順位、名前、性別という3項目で、10人程度のリストデータがあります。 data.csv(カンマ区切り)を編集するようにしていますが、順位は重複してはならないので、重複していたらエラーを出したいのですが。。。 ($rank,$name,$sex) = split(/\,/,$line); です。 open(IN,"$logfile") || &error("ファイルが開けません"); @lines = <IN>; close(IN); # 情報の書換え foreach $line (@lines) { ($rank,$name,$sex) = split(/\,/,$line); $line = "$in{'rank'},$name,$sex\n";} push(@new,$line); } # ファイルを更新 open(OUT,">$logfile") || &error("ファイルが開けません"); print OUT @new; close(OUT);

みんなの回答

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.5

in という名前のハッシュを使っているところからして、cgi-lib.pl を使ってますね? であれば、 > use strict; > use warnings; と >my %in; は削除してください。 しかしなんでピンポイントで、条件判定のところだけ 書き換えるということを試さないのでしょうか?

great_man2
質問者

お礼

cgi-lib.plは使っていません(^^; だめみたいです。 「しかしなんでピンポイントで、条件判定のところだけ 書き換えるということを試さないのでしょうか?」 logfileのCSVへのパスをどこに書けばいいのか分からずエラーを聞いたくらいのでレベルでして。。。 試行錯誤しながら作成していますが、「条件判定の所だけ書き換える」という事すら出来ないので・・・ あきらめますありとうございました

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.4

「教授」はしてません :-) >No such file or directory 理由がちゃんと書いてあるじゃないですか。 $logfileにログファイルの名前をいれとかないと正常動作しません。

great_man2
質問者

補足

ダメみたいです。 my $logfile = ./ranking.csv";と指定しましたが、 編集したらランキングの順位の列だけ全部空白で更新されてしまいました

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.3

まだよくわからんないところがあるんだけど、 4位以下のデータってファイルに出力する必要があるの? 1位から3位までのデータが取れればいいのでしょう? とりあえず4位以上は重複してもスルーするというだけならこんな感じ? #1の回答をベースにさせていただきましたが、 スタイルは自分好みのものに変えてますのであしからず。 use strict; use warnings; my %in; my $logfile; open my $fin, '<', $logfile or &error("ファイルが開けません ($!)"); my @lines = <$fin>; close $fin; # 情報の書換え my %seen; my @new; foreach my $line (@lines) { my ($rank, $name, $sex) = split q{,} ,$line; $line = "$in{'rank'},$name,$sex\n"; if ($seen{$rank}++ && $rank < 4) { &error("$rankは設定されています<br>現在の$rankをランク外にしてから再度設定してください。"); } push @new, $line; } # ファイルを更新 open my $fout, '>', $logfile or &error("ファイルが開けません ($!)"); print $fout @new; close $fout;

great_man2
質問者

補足

当方、全くの素人でして。。。 とりあえず、regist.cgiで、$rank, $name, $sexを入力。 edit.cgiで$rankだけ編集。 search.cgiで1位、2位、3位だけ表示としています。 ですので、edit.cgiで編集する際は全員のデータを編集するしか方法が分かりませんでした。。。 今、ご教授頂いたソースで実行すると、ファイルが開けません (No such file or directory) となってまいました。。。(^^;

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.2

>順位は重複してはならないので、重複していたらエラーを出したい というのに >4位以下は"9"としています(^^; という条件がついてるのがよくわかりません。 もう少し具体的なデータを例示したほうがよいように思います。 1~3位の中でだけ重複があるかどうかをチェックすればいい話なのか 順位のデータは'9' になっているけど別のフィールドを見てから 重複しているかどうかを判定しなければならないかとか。

great_man2
質問者

補足

すみません。わかりにくくて・・・ 合計20名~25名の名前と順位をCSVデータにして、 上位3位だけranking.cgiとしてCGIで表示するようにしています。 edit.cgiでCSVを編集する際には、上位3名だけ、1,2,3としていして、ランキング外のデータは全部4以上にして表示しないようにすれば完成なんですが。。。 1~3位まで重複チェックをして、ランク外は重複チェックしなくていいのです(^^;

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

「順位をキーとするハッシュ」を使うのが標準的かなぁ. 例えば %seen というハッシュに対して $seen{$rank}++; とすると, 既に $rank と同じ値を持つデータが出ていれば 0 以外の値が返りますし, そのようなデータがまだなければ 0 を返します. だから if ($seen{$rank}++) { 当該データは既出 } という形で処理できます.

great_man2
質問者

補足

ありがとうございます(^^; 下記のように明記しましたが、すみません。私の明記不足でした(^^; 上位1位、2位、3位だけデータに1,2,3と入っていて、4位以下は"9"としています(^^; 下記のように変更して実行すると、どの作業でも「設定されています」となってしまいます。 open(IN,"$logfile") || &error("ファイルが開けません"); @lines = <IN>; close(IN); # 情報の書換え foreach $line (@lines) { ($rank,$name,$sex) = split(/\,/,$line); $line = "$in{'rank'},$name,$sex\n";} if ($seen{$rank}++) { &error("$rankは設定されています<br>現在の$rankをランク外にしてから再度設定してください。");} push(@new,$line); } # ファイルを更新 open(OUT,">$logfile") || &error("ファイルが開けません"); print OUT @new; close(OUT);

関連するQ&A