CGI-BBS > CGI > Perl > CSVから条件に合うデーターを抽出して@配列に代入したい


カレッヂ
カレッヂ


質問者 やまあらし  投稿日 5/9(木) 02:53:00
ここのページ最近私の物ばかりになってきました・・・
並びにしあわせのツボ様いつもいつもありがとうございます。
今回もここでお世話になります。(自分の周りにこういったことが詳しい人がいないのと
自分の頭のCPUがイマイチなのがここに来る理由です・・実験してたらパソコン止まって
しまいました とほほです)前置き長くなりましたが

データーファイル(data.dat)にあるコンマ区切りデーターが何行かあり
1,山田,東京,22歳
10,山下,神奈川,25歳
14,大山,東京,30歳
25,田中,神奈川,45歳

これを配列変数@listに入れるまでは分かるのです

#!/usr/local/bin/perl
print "Content-type: text/html\n\n";

$a = "神奈川";
$b = "東京";

# ファイルのを読み込む
if(!open A,"data.dat"){
        print "データファイルを開けません。<hr size=1>";
        exit;
}
@list=<A>;#データーを@配列に入れる
$list=@list;#総データー数を代入
close(A);

これを神奈川に住む人だけを抽出して新しく@new_listに代入させようと苦心しています
私が考えたのは、抽出基準が左から3番目なので

if (split(/\,/)[2]) eq "$a") {
  真の値の処理法法が分からない(@new_list=@list ではダメですよね・・・)
}else {
  一致しなかったデーターはどうすればいいか?(何もしなくて良い?else以降は不要?)
}

ここまでの処理で@new_listに神奈川の2人だけが入っていれば良いのですができません

その後、年齢順でソートもしようと思うので、スプリットぜずに抽出したい
のですが、そもそも考え方(if構文を使う)が合っているのでしょうか
あっていても抽出基準の指定方法があっているのか
どこまでが良くてどこからがダメなのかが全く分かりません
ひたすらエラ−ばかりです・・・・。

こんな未熟者に良い知恵をお願いします。




回答者 しあわせのツボ  [削除]  投稿日 5/9(木) 11:38:18
ご指名のようですので。(笑)

まず、リストの全項目について処理をしたい場合はforeachを使う必要があります。
foreach文の中で、1項目ずつifで判定していけばいい訳です。
(ごく普通のifですから、elseが省略できることはおわかりでしょう)
で、配列に項目を追加するにはpushすればいいでしょう。

教科書的に書けばこうなります:
foreach $data (@list) {
        if ((split(/\,/, $data)[2]) eq "$a") { push(@new_line, $data); }
}

通常はこう書くでしょう:
foreach (@list) {
        if ((split(/\,/)[2]) eq $a) { push(@new_line, $_); }
}

これで、@listのうち条件を満たすものだけが@new_listに入ります。
必要ならあとで適宜splitなり何なりしてください。


おまけ。
「配列から特定の条件を満たす項目だけを抽出する」という作業はよく発生するので、実はそれ用にgrepという関数があったりします。
私ならこう書きます:
@new_list = grep(/.*?\,.*?\,$a\,/, @list);
質問者 やまあらし  [削除]  投稿日 5/9(木) 19:25:48
指名してしまったようです・・・。ほんと ありがとうございます。

foreachを使うのですか なるほど
で使ってみたのですが エラーがでてしまいました
ひょっとして ループから抜ける文が必要なのかと思いつつ
最後のおまけ grep を使うと なんとびっくり すっと動きました
それで、これからはこの関数を使おうと思うのですが

@new_list = grep(/.*?\,.*?\,$a\,/, @list);

だいたいの意味と仕組みは分かったのですがで//間のマッチパターンの意味を
考えたのですが

/.*?\,.*?\,$a\,/は、

読み込んだ1行分のデーターから$aにマッチする物を返すと言うことで良いのでしょうか?

.*?\,←これ1組で 0番のデーターと , になる 3番目だから2組と$aで良い

のですよね。(減してみたら2番目になりました)

私が苦手なメタ文字・パターンマッチです。5番目ならこの組み合わせを増やして
いけばいいわけですね

しかしつくづく思うのは、CGIは、いろんな関数の特徴を理解し上手に組み立てる
能力が必要ですね、int関数使って十の位切り捨てするのに1晩悩んで、
でてきた結果が小学生クラスの考え・・・・ 100で割って捨てて100掛ける・・・
頭を柔らかくすることも必要だなと思いました。
私の頭はまだ固い石のようです・・
今回も大変お世話になりました、パーターンマッチ勉強します。
ありがとうございました。


返信(回答)する


Web裏技