匿名質問者

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人5回まで
  • 登録:
  • 終了:2016/10/19 09:13:38

ベストアンサー

匿名回答1号 No.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年近く前のものだと思われます。
出来れば最近のメンテナンスされてるものを使った方が良いと思いますけどね……

他1件のコメントを見る
匿名回答1号

コードあるので本文に追記しました。

2016/10/17 18:54:17
匿名質問者

ありがとうございます。
無事希望通りに表示できました。

2016/10/19 09:12:58

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません