人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

cgi(perl)で日付順でソートして同じ日付なら登録順にソートする方法

open (FILE, "$data") || &error("error");
@data = <FILE>;
close(FILE);

# カウント除去
$count = shift (@data);
foreach (@data) {
($no,$contents,$date,$year,$month,$day,$comment,$new,$url) = split(/<>/);
@tmp = ();
@tmp = map {(split /<>/)[2]} @data;
@data = @data[sort {$tmp[$b] cmp $tmp[$a]} 0 .. $#tmp];
}
$noが登録順、$dateが日付を8ケタにまとめた物(20161014等)です。

現在、登録日で並べるようにしていますが、同じ日付のものがいくつかあるとその中で変な並びになってしまいます。
日付でソートし、さらに登録順で掲載するにはどのように修正したらよいでしょうか?

●質問者: 匿名質問者
●カテゴリ:ウェブ制作
○ 状態 :終了
└ 回答数 : 1/1件

▽最新の回答へ

1 ● 匿名回答1号
ベストアンサー

そのコードって実際に使ってる奴まんまの抜きだし?
正直ありえないんで、本当にこんなコードならよそもボロボロつーか危険な臭いがしてそう。
言うなれば廃墟。正直、作り直すか諦めるかして欲しい。perl知ってる人いない?

一応、ソートに関してはシュワルツ変換ってのがあるんでお節介しておく。
http://www.k1s.jp/blog.cgi?n=149&category=201
http://blog.remora.cx/2010/05/schwartzian-transform-in-perl-and-python.html

open (FILE, "<", $data) or error("error");
($count, @data) = <FILE>;
close(FILE);
#($no,$contents,$date,$year,$month,$day,$comment,$new,$url) = split(/<>/);

@data =
 map {$_->[0]}
 sort {$b->[3] cmp $a->[3] or $a->[1] <=> $b->[1]}
 map {[$_, split /<>/]}
 @data

まあ、一番気になるのは $data がどっから出てきたのっていう。
変な所じゃなきゃ良いけど。

----

[追記]
おっと、最後に";"がなかった。
あと、もしかしてって思ったのが当たってた……
186行目「chomp;」までの置き換えです。

open (FILE, "<", $data) or error("error");
($count, @data) = <FILE>;
close(FILE);

@splitdata =
 sort {$b->[3] cmp $a->[3] or $a->[1] <=> $b->[1]}
 map {[$_, split /<>/]}
 @data;
@data = map {$_->[0]} @splitdata;

foreach $data (@splitdata) {
 ($data,$no,$contents,$date,$year,$month,$day,$comment,$new,$url) = @$data;
     ##ここから繰り返し表示部分##

split2回も3回もいりません。1回で充分です。
chompも無意味なのでいりません。
てな感じでどこで拾ってきたのかは分かりませんが、無意味なことを無駄にやってます。
このコードも@dataや$dataを整えてますが、これ以降で使わないなら、その部分は無駄です。
書き方からして20年近く前のものだと思われます。
出来れば最近のメンテナンスされてるものを使った方が良いと思いますけどね……


匿名質問者さんのコメント
返答ありがとうございます。 ネットからダウンロードしてきたcgiで、多分結構古いものだと思われます。 $dataはデータが保存されているファイルです。 # データファイル名 $data = './date.dat'; そのまま入れ替えてみたのですが、500エラーになりました。 エラーが出た所が指示のあった所の続きの場所だったので記載します。 open (FILE, "<", $data) or error("error"); ($count, @data) = <FILE>; close(FILE); #($no,$contents,$date,$year,$month,$day,$comment,$new,$url) = split(/<>/); @data = map {$_->[0]} sort {$b->[3] cmp $a->[3] or $a->[1] <=> $b->[1]} map {[$_, split /<>/]} @data foreach $data (@data) { ($no,$contents,$date,$year,$month,$day,$comment,$new,$url) = split(/<>/,$data); chomp; ##ここから繰り返し表示部分## ---エラー内容---- syntax error at news.cgi line 184, near "$data (" syntax error at news.cgi line 203, near "}" syntax error at news.cgi line 227, near "}" ?("}"が1つ多い?) ----- 184行目は「foreach $data (@data) {」です。

匿名回答1号さんのコメント
コードあるので本文に追記しました。

匿名質問者さんのコメント
ありがとうございます。 無事希望通りに表示できました。
関連質問

●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ