• ベストアンサー

切り分けてソート(?)

CGIを改造しようと努力中です。 イベント開催一覧のようなものを表示させたいので、更新記録CGIを改造しつつ自分の目的にあった表示にしたいと思っています。 この中で、日付ごとに表示をさせたいと思っています。 「$no,$titles,$comment,$img,$date」の形でログに保存していっています。 もちろん「$date」の項目に日付が入っているのですが、「2005/00/00~2005/00/00」または「2005/00/00~00/00」という「開始日と終了日」で保存されています。これを終了日でソートし、早く終わるものを一番上に持って来たいのです。 しかし、方法がさっぱりです。 概念的には… 1.$dateの「~」の前までを削除する 2.日付を数字に変換(?) 3.ソートして一旦格納 4.foreachで表示を繰り返す って感じですよね? この1~3の仕方がさっぱりわかりません。方法を教えてください。 言語はジャンルでも書いてあるとおりperlです。 抜けている情報があったら指摘してください。すぐに書込みします。 以上お願いします。

  • Perl
  • 回答数10
  • ありがとう数7

質問者が選んだベストアンサー

  • ベストアンサー
  • xyz37005
  • ベストアンサー率51% (363/708)
回答No.8

>この方法だと開始日の方でソートしていませんか?終了日の方が微妙にソートできていなかったので… >終了日の方でソートしたいのですが、お願るでしょうか? こういうことを書くのであれば、 どうのような入力データでどのような出力がされたかも書いてください。 少なくとも私の環境ではきちんと終了日でソートされてました。 みなさん ・「$no,$titles,$comment,$img,$date」の形でログに保存 ・「$date」は「2005/00/00~2005/00/00」または「2005/00/00~00/00」の形式 を前提としてアドバイスされてます。データ形式が違えば当然出力も違ってきます。 質問をされる際には正しい情報でお願いします。 なお、下記は区切り文字を<>に変更してあります。 ○スクリプト例 ------------------------------------------------------------------------------ #!C:/perl/bin/perl @event_data = ( "1<>イベント1<>コメント1<>イメージ1<>2005/01/01~2005/01/02" , "2<>イベント2<>コメント2<>イメージ2<>2005/02/01~2005/02/02" , "3<>イベント3<>コメント3<>イメージ3<>2005/03/01~03/02" , "4<>イベント4<>コメント4<>イメージ4<>2005/04/01~04/02" , "5<>イベント5<>コメント5<>イメージ5<>2005/01/11~01/12" , "6<>イベント6<>コメント6<>イメージ6<>2005/02/11~02/12" , "7<>イベント7<>コメント7<>イメージ7<>2005/03/11~2005/03/12" , "8<>イベント8<>コメント8<>イメージ8<>2005/04/11~2005/04/12" , "9<>イベント9<>コメント9<>イメージ9<>2005/5/1~2005/5/31" , "10<>イベント10<>コメント10<>イメージ10<>2005/05/02~2005/05/30" , "11<>イベント11<>コメント11<>イメージ11<>2005/5/3~5/29" , "12<>イベント12<>コメント12<>イメージ12<>2005/05/04~05/28" , "13<>イベント13<>コメント13<>イメージ13<>2005/06/01~06/10" , "14<>イベント14<>コメント14<>イメージ14<>2005/6/2~6/9" , "15<>イベント15<>コメント15<>イメージ15<>2005/06/03~2005/06/8" , "16<>イベント16<>コメント16<>イメージ16<>2005/6/4~2005/6/7" ) ; @new_event_data = ( ) ; foreach $tmp_event_date ( @event_data ){ ( $no , $titles , $comment , $img , $date ) = split( /<>/ , $tmp_event_date ) ; if( $date =~ /^[0-9]{4}\/[0-9]{1,2}\/[0-9]{1,2}~([0-9]{4})\/([0-9]{1,2})\/([0-9]{1,2})$/ ){ $end_date = sprintf( "%04d%02d%02d" , $1 , $2 , $3 ) ; }elsif( $date =~ /^([0-9]{4})\/[0-9]{1,2}\/[0-9]{1,2}~([0-9]{1,2})\/([0-9]{1,2})$/ ){ $end_date = sprintf( "%04d%02d%02d" , $1 , $2 , $3 ) ; } push( @new_event_data , $end_date . "," . $tmp_event_date ) ; } @new_event_data = sort( @new_event_data ) ; print <<HTML ; Content-type: text/html <html> <head> <title>テスト</title> </head> <body> <table border=4 width=250 align=center> <tr bgcolor="#cccccc"> <th>no</th> <th>titles</th> <th>comment</th> <th>img</th> <th>date</th> </tr> HTML foreach $tmp_new_event_date ( @new_event_data ){ $tmp_new_event_date =~ s/^[0-9]{4}[0-9]{2}[0-9]{2},// ; ( $no , $titles , $comment , $img , $date ) = split( /<>/ , $tmp_new_event_date ) ; print <<HTML ; <tr align=center> <td>$no</td> <td>$titles</td> <td>$comment</td> <td>$img</td> <td>$date</td> </tr> HTML } print <<HTML ; </table> </body> </html> HTML ------------------------------------------------------------------------------ 参考にPerlを使ったCGIについてわかりやすく書いたHPを紹介します。 ここを見て勉強することをお勧めします。

参考URL:
http://www.tohoho-web.com/
master-3rd
質問者

お礼

返答遅くなってすみません。 無事この方法で完璧なソートが出来ました。 ありがとうございました。

その他の回答 (9)

回答No.10

#3です。 #4さんの処理をパクってます( ´∀`) --- ここから ----- #ソートのキー(終了日)を抜き出し配列(@tmp1)に入れる #この際、年が付いていない場合は、開始日の年を #入れる。 @tmp1 = map{ join '' , $_ =~ m<(\d{4}/)(?:\d{1,2}/\d{1,2}~)?(\d{1,2}/\d{1,2})$> } @event_data; #ソート用に月、日を2桁に変更 $_ = sprintf( "%04d/%02d/%02d", split("/",$_)) for @tmp1; #ソート処理 @data = @event_data[ sort{ $tmp1[$a] cmp $tmp1[$b] } 0..$#tmp1]; #表示部 foreach $data (@data){ ($no,$titles,$comment,$img,$date) = split (/<>/,$data); print "<TR>\n"; print " <TD>$titles</TD>\n"; print " <TD>$date</TD>\n"; print "</TR>\n"; } --- ここまで ------ たぶん、これを見ただけでは何をしようとしているか 判らないと思います。 やってる事を順次説明します。 @tmp1 = map{ join '' , $_ =~ m<(\d{4}/)(?:\d{1,2}/\d{1,2}~)?(\d{1,2}/\d{1,2})$> } @event_data; この部分ですが、簡単に言うと終了日を抜き出し @tmp1に入れています。 m<・・・・・・>の部分は判りにくいとは思いますが やってる事は、終了日を抜き出し、年が無ければ 開始日の年をくっつけるという処理になってます。 それらを@tmp1に入れていって、終了日の配列を 作ります。 $_ = sprintf( "%04d/%02d/%02d", split("/",$_)) for @tmp1; ここでは、@tmp1に入っている終了日を ****/*/* → ****/**/**の形に変換をかけています。 なぜ変換するかというと、ソートをする時に 2005/07/01 と2005/11/01の場合、2005/11/01が 大きいと判断できるのですが 2005/7/1 と2005/11/01の場合、 「2005/7」と「2005/1」が比較され、2005/7/1が 大きいと判断してしまうからです。 @data = @event_data[ sort{ $tmp1[$a] cmp $tmp1[$b] } 0..$#tmp1]; ソート処理です。 簡単に言うと、@tmp1をソートし、その結果 (配列番号順)通りに@event_dataを@dataに 入れています。 簡単な例で説明すると 名簿があり、出席番号、名前、体重という構成に なっているとします。(変な名簿ですが・・) #@event_dataが名簿全体の配列を表し #@tmp1は出席番号、体重という配列を表します。 この時、@tmp1を体重順でソートすると 出席番号の順番も変わりますよね? その出席番号順に、名簿全体を並び変える処理が 上の処理です。 表示部は・・・まぁ判りますよね(´・ω・`) あと気になったのですが、終了日が同じ場合 開始日順でもソートをするのでしょうか? その場合は、 @tmp1を抜き出す処理の次に @tmp2 = map{ join '' , $_ =~ m<(\d{4}/\d{1,2}/\d{1,2})~> } @event_data; $_ = sprintf( "%04d/%02d/%02d", split("/",$_)) for @tmp2; を追加し ソート処理を @data = @event_data[ sort{ $tmp1[$a] cmp $tmp1[$b] or $tmp2[$a] cmp $tmp2[$b] } 0 .. $#tmp1 ]; に差し替えてください。

  • leaz024
  • ベストアンサー率75% (398/526)
回答No.9

No.7 でテスト中のコードを書いてしまいました。。。 ソート部分は正しくはこうなります。 @data = map {$_->[0]} sort {$a->[1] cmp $b->[1]} map {[$_, sprintf('%04d%02d%02d', m<(\d{4})/(?:\d+/\d+~)?(\d+)/(\d+)$>)]} @data;

  • leaz024
  • ベストアンサー率75% (398/526)
回答No.7

何だか質問文とはずいぶん仕様が違ってきてますが、それに合わせたものを再掲。 ※データは <> 区切り ※日付の月日はゼロ埋めなし @data = <IN>; # ソート(長いけど1行です。) @data = map {$_->[0]} sort {$a->[1] cmp $b->[1]} map {[$_, join('', m<(\d{4}/)(?:\d+/\d+~)?(\d+/\d+)$>)]} @data; # 表示 foreach $data (@data){ chomp($data); ($no, $titles, $comment, $img, $date) = split(/<>/, $data); print "$titles : $date\n"; }

  • xyz37005
  • ベストアンサー率51% (363/708)
回答No.6

文字列をある文字で分割したい場合は通常splitを使います。 http://www2u.biglobe.ne.jp/~MAS/perl/ref/split.html ○スクリプト例 ------------------------------------------------------------------------------ #!C:/Perl/bin/perl @event_data = ( "1,イベント1,コメント1,イメージ1,2005/01/01~2005/01/02" , "2,イベント2,コメント2,イメージ2,2005/02/01~2005/02/02" , "3,イベント3,コメント3,イメージ3,2005/03/01~03/02" , "4,イベント4,コメント4,イメージ4,2005/04/01~04/02" , "5,イベント5,コメント5,イメージ5,2005/01/11~01/12" , "6,イベント6,コメント6,イメージ6,2005/02/11~02/12" , "7,イベント7,コメント7,イメージ7,2005/04/11~2005/03/12" , "8,イベント8,コメント8,イメージ8,2005/04/11~2005/04/12" , ) ; @new_event_data = ( ) ; foreach $tmp_event_date ( @event_data ){ ( $no , $titles , $comment , $img , $date ) = split( /,/ , $tmp_event_date ) ; ( $start_date , $end_date ) = split( /~/ , $date ) ; if( $end_date =~ /^[0-9]{2}\/[0-9]{2}$/ ){ ( $year , $dummy ) = split( /\// , $start_date ) ; $end_date = $year . $end_date ; } $end_date =~ s/\///g ; push( @new_event_data , $end_date . "," . $tmp_event_date ) ; } @new_event_data = sort( @new_event_data ) ; print <<HTML ; Content-type: text/html <html> <head> <title>テスト</title> </head> <body> <table border=4 width=250 align=center> <tr bgcolor="#cccccc"> <th>no</th> <th>titles</th> <th>comment</th> <th>img</th> <th>date</th> </tr> HTML foreach $tmp_new_event_date ( @new_event_data ){ $tmp_new_event_date =~ s/^[0-9]{4}[0-9]{2}[0-9]{2},// ; # print "$tmp_new_event_date\n" ; ( $no , $titles , $comment , $img , $date ) = split( /,/ , $tmp_new_event_date ) ; print <<HTML ; <tr align=center> <td>$no</td> <td>$titles</td> <td>$comment</td> <td>$img</td> <td>$date</td> </tr> HTML } print <<HTML ; </table> </body> </html> HTML ------------------------------------------------------------------------------ ※これはあくまで例です。先頭の"#!C:/Perl/bin/perl"を初め自分の環境などに合わせて書き換えてください。 ところで >あと、保存されているログが<>で区切られているので、 って、","区切りじゃないの? もし"<>"区切りならsplitとかの区切り文字変えてね。 それからNo.5の記事にある補足についてですが ソートされてないのは日付がyyyy/mm/ddの形になってないから。 一桁の月とか日とかも先頭に0を詰めなきゃダメですよ。 例:今日なら2005/7/5でなく2005/07/05と表記。 最初の質問で >、「2005/00/00~2005/00/00」または「2005/00/00~00/00」 とあるので皆さんそれ前提で考えてるんですよ。

master-3rd
質問者

補足

何度も返答すみません。 ソートちゃんとうまくいきました。しかし1つだけ問題が… この方法だと開始日の方でソートしていませんか?終了日の方が微妙にソートできていなかったので… 終了日の方でソートしたいのですが、お願るでしょうか? >例:今日なら2005/7/5でなく2005/07/05と表記。 これは、0/0で今までやってきたのですが、このままの書き方でいく場合、そのためにまた色々と変更が必要ですか? 難しいようだったらこのままで良いのですが、やはり0/0表記の方がスマートなので… こちらもお願いできるでしょうか。 色々と注文ばかりで済みませんが、お願いします。<(_ _)>

  • cascade
  • ベストアンサー率24% (35/144)
回答No.5

#1です。 専門家さんがいらっしゃる中、 シロートが書くのも恥ずかしいですけど あえて自分の路線を曲げずにいきますw 質問者さんのソースをちょびっと書き換えて、 さらに終了日の"年"部分は無くてもいいように改造しました。 データは#3さんのパクリです。 #見づらくてごめんなさい。 #コピペでも使えるように半角スペースのままです。 ○コード #@data = <IN>; #↓ファイルから読み取ったものする(なので最後にLFが付いてる) @data = ( "1,イベ1,コメ1,イメ1,2005/01/01~2005/02/10\n", "2,イベ2,コメ2,イメ2,2005/01/15~2005/02/02\n", "3,イベ3,コメ3,イメ3,2005/03/01~07/25\n", "4,イベ4,コメ4,イメ4,2005/04/01~04/15\n", "5,イベ5,コメ5,イメ5,2005/04/01~05/31\n", "6,イベ6,コメ6,イメ6,2005/05/01~05/22\n", "7,イベ7,コメ7,イメ7,2005/05/11~2005/05/18\n", "8,イベ8,コメ8,イメ8,2005/06/01~2005/06/30\n", ) ; ### ここでソートする。 @sort_array = sort sort_func @data; #sort_funcに従ってソート sub sort_func { my @tmp; my $aa = (split /,/, $a)[4]; #レコードから$dateを取り出す @tmp = split /~/, $aa; #開始日/終了日を分離 if ($tmp[1] !~ /^\d{4}\//) { #"年"がなければ開始日から抜き出してくっつける $aa = (split /\//, $tmp[0])[0] . "/" . $tmp[1]; } my $bb = (split /,/, $b)[4]; @tmp = split /~/, $bb; if ($tmp[1] !~ /^\d{4}\//) { $bb = (split /\//, $tmp[0])[0] . "/" . $tmp[1]; } return($aa cmp $bb); #終了日の日付が古い順ならこっち # return($bb cmp $aa); #終了日の日付が新しい順ならこっち } foreach $sort_array (@sort_array){ # ($no,$titles,$comment,$img,$date) = split(/<>/,$sort_array); ($no,$titles,$comment,$img,$date) = split(/,/,$sort_array); # chomp; print $no, ":", $date; } ○結果 1:2005/01/01~2005/02/10 2:2005/01/15~2005/02/02 4:2005/04/01~04/15 7:2005/05/11~2005/05/18 6:2005/05/01~05/22 5:2005/04/01~05/31 8:2005/06/01~2005/06/30 3:2005/03/01~07/25

master-3rd
質問者

補足

更なる返答ありがとうございます。 しかし、微妙に惜しいです。ソートはしているようなのですが、ちゃんと順番通りになってません。 まずは、このままコピペしたところログの数だけ表は出るのですが表示しませんでした。 ソースを見ると、Noのところにすべて表示してしまってました。なので、 ($no,$titles,$comment,$img,$date) = split(/<>/,$sort_array); #($no,$titles,$comment,$img,$date) = split(/,/,$sort_array); こう変えてみたところ表示はするようになりました。 しかし、いまだソートはせず…(T_T) あと、保存されているログが<>で区切られているので、 my $aa = (split /<>/, $a)[4]; my $bb = (split /<>/, $b)[4]; としてみました。 変化はあったのですが、日付の通りにはなっていません。しかも、どういう法則でソートされているのかがさっぱりです。(return($aa cmp $bb)を入れ替えると、上下反転するので、正常に動作はしているのですが…) 現在の結果は… 2005/07/9~2005/07/10 2005/5/10~2005/5/20 2005/5/10~2005/5/31 2005/5/10~2005/6/19 2005/5/10~2005/7/31 2005/5/11~2005/6/19 って感じで並んでます。 すみません。解決方法をお願いします。

  • leaz024
  • ベストアンサー率75% (398/526)
回答No.4

@data = map {$_->[0]}          sort {$a->[1] cmp $b->[1]}             map {[$_, get_end_date($_)]}                @data; print "$_\n" for @data; sub get_end_date {   join '', $_[0] =~ m<(\d{4}/)(?:\d\d/\d\d~)?(\d\d/\d\d)$>; } この手のソートをする時は sort の比較式の中でログを分解すると効率が悪いので、予め比較部分を用意してソートするようにします。 ※この考え方については、参考URLに詳しく載っています。 終了日は「年」のある/なしが統一されていないので、年付きに統一して比較する必要があります。次の正規表現で年(終了日に年があればそれを、なければ開始日の年を取り出す)と月日のリストが得られるので、それを連結して終了日とします。   m<(\d{4}/)(?:\d\d/\d\d~)?(\d\d/\d\d)$> なお、日付は文字列としてソート可能なので、数値に変換する必要はありません。 また、今回は日付部分がデータ末尾に付いていたので簡単に処理しましたが、途中にある場合は split などで抜き出してから処理して下さい。 ※インデントに全角空白を使っているので、コピーする場合はタブなどに置換して下さい。

参考URL:
http://www.din.or.jp/~ohzaki/perl.htm#SortST
回答No.3

面白そうだったので、荒業に挑戦してみました。 #たぶん参考にはならないと思います・・ #データなどはNo.2さんを参考にしてます。 #インデントには全角空白を使っているので #コピペの際は半角に変えてください。 @event_data = ( "1,イベ1,コメ1,イメ1,2005/01/01~2005/02/10", "2,イベ2,コメ2,イメ2,2005/01/15~2005/02/02", "3,イベ3,コメ3,イメ3,2005/03/01~07/25", "4,イベ4,コメ4,イメ4,2005/04/01~04/15", "5,イベ5,コメ5,イメ5,2005/04/01~05/31", "6,イベ6,コメ6,イメ6,2005/05/01~05/22", "7,イベ7,コメ7,イメ7,2005/05/11~2005/05/18", "8,イベ8,コメ8,イメ8,2005/06/01~2005/06/30", ) ; foreach $event (  sort {   ((split("~",$a))[1] =~ /^\d{2}\/\d{2}$/ ?    join("",(split("/",(split(",",$a))[4]))[0],     (split("/",(split("~",$a))[1])))    : join("",(split("/",(split("~",$a))[1]))))   <=>   ((split("~",$b))[1] =~ /^\d{2}\/\d{2}$/ ?    join("",(split("/",(split(",",$b))[4]))[0],     (split("/",(split("~",$b))[1])))    : join("",(split("/",(split("~",$b))[1]))))  }@event_data){  print "$event\n"; } 結果 2,イベ2,コメ2,イメ2,2005/01/15~2005/02/02 1,イベ1,コメ1,イメ1,2005/01/01~2005/02/10 4,イベ4,コメ4,イメ4,2005/04/01~04/15 7,イベ7,コメ7,イメ7,2005/05/11~2005/05/18 6,イベ6,コメ6,イメ6,2005/05/01~05/22 5,イベ5,コメ5,イメ5,2005/04/01~05/31 8,イベ8,コメ8,イメ8,2005/06/01~2005/06/30 3,イベ3,コメ3,イメ3,2005/03/01~07/25 解説 foreach()内のsortで、年がついてるかどうかの 比較をし、無かったら開始日の年をつけて 一旦終了日を"年月日"に作り変えます。 その形でソートさせて、表示しています。 結局は、読みづらいだけですね( ´∀`)

  • xyz37005
  • ベストアンサー率51% (363/708)
回答No.2

○スクリプト例 #!/usr/local/bin/perl @event_data = ( "1,イベント1,コメント1,イメージ1,2005/01/01~2005/01/02" , "2,イベント2,コメント2,イメージ2,2005/02/01~2005/02/02" , "3,イベント3,コメント3,イメージ3,2005/03/01~03/02" , "4,イベント4,コメント4,イメージ4,2005/04/01~04/02" , "5,イベント5,コメント5,イメージ5,2005/01/11~01/12" , "6,イベント6,コメント6,イメージ6,2005/02/11~02/12" , "7,イベント7,コメント7,イメージ7,2005/04/11~2005/03/12" , "8,イベント8,コメント8,イメージ8,2005/04/11~2005/04/12" , ) ; @new_event_data = ( ) ; foreach $tmp_event_date ( @event_data ){ ( $no , $titles , $comment , $img , $date ) = split( /,/ , $tmp_event_date ) ; ( $start_date , $end_date ) = split( /~/ , $date ) ; if( $end_date =~ /^[0-9]{2}\/[0-9]{2}$/ ){ ( $year , $dummy ) = split( /\// , $start_date ) ; $end_date = $year . $end_date ; } $end_date =~ s/\///g ; push( @new_event_data , $end_date . "," . $tmp_event_date ) ; } @new_event_data = sort( @new_event_data ) ; foreach $tmp_new_event_date ( @new_event_data ){ $tmp_new_event_date =~ s/^[0-9]{4}[0-9]{2}[0-9]{2},// ; print "$tmp_new_event_date\n" ; } ○出力結果 1,イベント1,コメント1,イメージ1,2005/01/01~2005/01/02 5,イベント5,コメント5,イメージ5,2005/01/11~01/12 2,イベント2,コメント2,イメージ2,2005/02/01~2005/02/02 6,イベント6,コメント6,イメージ6,2005/02/11~02/12 3,イベント3,コメント3,イメージ3,2005/03/01~03/02 7,イベント7,コメント7,イメージ7,2005/04/11~2005/03/12 4,イベント4,コメント4,イメージ4,2005/04/01~04/02 8,イベント8,コメント8,イメージ8,2005/04/11~2005/04/12

master-3rd
質問者

お礼

すみません。補足を使ってしまったので、御礼の欄で追加情報を記入します。 最終的に以下のような形で表示したいです。 foreach $data (@data){ ($no,$titles,$comment,$img,$date) = split(/<>/,$data); chomp; print "<TR>\n"; print "<TD>$titles</TD><TD>$date</TD>\n"; print "<TR><TD>\n"; ~~ (もちろん、「 $data・@data」に関しては変更可能です) ここに当てはめる事が出来るような形で回答をお願いできるでしょうか?素人なので、それ以上の修正がうまく出来ません。 以上、お願いいたします。

master-3rd
質問者

補足

返答ありがとうございます。 出力結果ですが、表を利用して一覧表のように出したいです。 $tmp_new_event_dateをそれぞれの変数に割るにはどうしたら良いのでしょう? 初歩的な質問ですみません。お願いします。

  • cascade
  • ベストアンサー率24% (35/144)
回答No.1

"$no,$titles,$comment,$img,$date"の配列が@dataに入っていたとして、 私がよくやる方法だとこんな感じです。 @sort_array = sort sort_func @data; #sort_funcに従ってソート sub sort_func { my $aa = (split /,/, $a)[4]; #レコードから$dateを取り出す $aa = (split /~/, $aa)[1]; #$dateから終了日を抜き出す my $bb = (split /,/, $b)[4]; #上と同じ $bb = (split /~/, $bb)[1]; # return($aa cmp $bb); #終了日の日付が古い順ならこっち # return($bb cmp $aa); #終了日の日付が新しい順ならこっち } 但し、これは終了日のところが必ず"年/月/日"となっていないと使えません。 "月/日"でもいいようにするにはsort_funcの中で"~"より前に付いてる "年"部分を"月/日"にくっつけてやればいいです。

master-3rd
質問者

補足

返答ありがとうございます。 えー。ナゼでしょう。うまく動作しません。 ---------- @data = <IN>; ### ここでソートする。 @sort_array = sort sort_func @data; #sort_funcに従ってソート sub sort_func { my $aa = (split /,/, $a)[4]; #レコードから$dateを取り出す $aa = (split /~/, $aa)[1]; #$dateから終了日を抜き出す my $bb = (split /,/, $b)[4]; #上と同じ $bb = (split /~/, $bb)[1]; # return($aa cmp $bb); #終了日の日付が古い順ならこっち # return($bb cmp $aa); #終了日の日付が新しい順ならこっち } foreach $sort_array (@sort_array){ ($no,$titles,$comment,$img,$date) = split(/<>/,$sort_array); chomp; print "~ 解決方法を教えてください。

関連するQ&A

  • ソートの方法

    某CGIを改造中です。 記事を更新日順でソートしなおしたいです。 多分、ソート部分だと思われる部分の現状は、 ----- foreach (@data) {   ($no,$year1,$month1,$day1,$name~~) = split(/<>/);   @tmp = ();   @tmp = map {(split /<>/)[0]} @data;   @data = @data[sort {$tmp[$b] cmp $tmp[$a]} 0 .. $#tmp]; } ----- です。 ただ、見ての通り、日付が「$year1,$month1,$day1」と分かれています。これを結合して(20060309のような形)、それを元にソートしなおしたいのですが、どのようにしたら良いでしょうか? 方法を教えてください。お願いします。

    • ベストアンサー
    • Perl
  • データファイルのソート方法について

    perlで使用している、データファイルのソート方法について質問いたします。 やりたいこと。 1.ファイルを読み込み 2.指定されている文字列でソートをして 3.同じファイルに格納する 以上になります。 以下のファイルにデーターが入ってます・ namedata.cgi 田中,4 佐藤,2 鈴木,1 水野,3 このファイルをソートして以下のように並び替えて保存したいと思ってます。 スクリプトを実行後 namedata.cgi 鈴木,1 佐藤,2 水野,3 田中,4 となっていてほしいのです。 スクリプト sort.cgi 略・・・ #ふぁいる読み込み open(DB,"<$file") || &error("Can't write $file"); flock(DB, 1); @lines = <DB>; close(DB); #ソート @result = sort { $a <=> $b } @lines; #ファイル書き込み open(DB,">$file") || &error("Can't write $file"); flock(DB, 2); print DB "@result"; close(DB); ファイルの2項目目が分からないからソートされていないような気がするのですが、記述方法がわかりません。 ファイル読み込み時にforeachを使用して読み込まないとだけなのでしょうか? うまく説明できていないかもしれませんが、よろしくお願いいたします。

    • ベストアンサー
    • Perl
  • WP2.7.1でコメントの日付の表記を変更

    ワードプレス2.7.1を使っています。 コメント表示の日付の表記が 2009 年 5 月 18 日 となっているので、 2009/5/18 と直したいのですが、どこをどうしたらいいのか… wp/wp-includes/comment-template.php の350行目あたりにそれっぽいのがあるのですが function get_comment_date( $d = '' ) { global $comment; if ( '' == $d ) $date = mysql2date( get_option('date_format'), $comment->comment_date); else $date = mysql2date($d, $comment->comment_date); return apply_filters('get_comment_date', $date); } これでしょうかね?色々やってみましたらエラーになります…

  • Live mail 2011 ソート機能がおかしい

    Windows Live mail 2011を使用しております。 メールにソート機能があるかと思いますが(受信されたメールを日付順で見たいなど) 日付でソートを行うと、同じ件名のメールが表示されないという現象が起こっており非常に困っています。どなたかこの現象を回復させる方法をご存じの方はいらっしゃいませんでしょうか。 分かり辛い部分等ございましたらご質問お願いいたします。

  • 2007/1/15形式をソートしたい

    予約カレンダーを作っています。 ユーザーは不特定の日を予約できます。 CSVファイル 2,1029,2007/1/15,C, 3,1029,2007/1/15,B,checked 4,1029,2007/1/10,D, 5,1029,2007/1/9,C,checked 6,1029,2007/1/16,D, 8,1023,2007/1/17,D 9,1023,2007/1/24,D 10,1023,2007/1/24,C 11,1023,2007/1/10,D ID,会員番号,日付,ステータス,承認 ソートがうまくいかず上記のように並んでいます。 理想としては 9,1023,2007/1/24,D 10,1023,2007/1/24,C 8,1023,2007/1/17,D 11,1023,2007/1/10,D のように日付が新しい方を上にして書き込みたいのです。 2007/1/24のところのソートが上手くいきません。 また、IDの順序も変わると新しいIDをつけるときに困りそうです。 なにかいい方法があったら教えてください。

    • ベストアンサー
    • Perl
  • macで写真を撮影日順にソートする方法。

    Finderで写真をソートする時、ソート項目に作成日や更新日しかなく、撮影日という項目が無いので困ってます。 作成日を見ると、撮影した日付ではなく、HDDに画像をコピーした日付になっており、 これではソートできません。 デジカメが一台なら名前順にソートすればいいのですが、2台のデジカメの写真をまとめたいので 名前順にソートすると機種別にパックリわかれてしまいます。(ファイル名が違うので) どうしたら、複数のデジカメで撮った写真を撮影日順にソートできますか? windowsならすぐできるのですが、macでやる方法が知りたいです。

    • ベストアンサー
    • Mac
  • 指定日になったら自動で情報変更

    各種イベントをホームページに掲載したいです。 更新記録CGIを改造して使いたいと思っているのですが、イベント終了時にそのデータを消さないといけないんですけど、忘れてしまいそうです。 そこで、イベント日付が過ぎたらその情報を非表示としたいのですが、そんなことできるのでしょうか? 今は、同じ名前のイベントを何度もすることがあるので、イベント名などをそのまま保持しておき、表示・非表示のチェックボックスをセットしてあります。また、日付は○月○日の形式で保存してます。(これは、必要であれば200○/○/○の形式に変更することは可能です) なので、イメージとしては 「もし、今日の日付よりイベントの日付が小さい場合、イベント表示チェックをはずす」 if($today>$event_day){$event_view=""}; こんな感じでしょうか? 今日の日付の取得方法や「$today>$event_day」の方法等がいまいち良くわかってないです。 また、これってどう設定したらいいのでしょうか? CGIって誰かが読み込まないと実行しないんですよね? どの部分で実行させるのがいいんでしょう? やっぱりデコード部分と一緒に記事を読み込んだ瞬間実施するってのが現実的なのでしょうか? CGIについてあまり理解できていないので、変な質問しているかもしれませんが、そのときは指摘してください。 お願いします。

  • 多次元配列でソートしたい

    たとえば、Yahooオークションとかで、「商品名」「価格」「残り日数」が表示されていて、 それぞれをクリックすると、その列をソートして全体を昇順・降順に並べ替えてくれますよね。 あれを自前のCGIで実現したいのです。 たとえば、3次元配列$hoge[X][Y][Z]を定義し、ここがクリックされたらXをキーにソート、ここがクリックされたらYでソートということをやりたいと思っているのですが、当然こういう機能は無いわけで、自分で作らなくてはいけません。 連想配列とかポインタとか色々考えたのですが、うまく行かず・・・。 どのような実装方法があるでしょうか、アイデアをお聞かせ願えたら嬉しいです。

    • ベストアンサー
    • Perl
  • 画像ファイルのアドレスに今日の日付を入れる

    例えば以下のようにHTMLに画像を表示させるタグがありますが、 <img src="http://www.hoge.tst/20060504.jpg"> このアドレスの日付部分(YYYYMMDD)を「JavaScript」で本日の日付に設定する方法はありますか? つまり、その日の日付をファイル名にした画像を表示させたいです。 CGIではなく、JavaScriptを使用した方法が希望です。 宜しくお願いします。

  • CGI「Key Search」日付だけ表示したい

    KentWebさんのサイト内検索CGI「Key Search」について、 今は↓このように http://www.kent-web.com/data/ksearch/ksearch.cgi?code=%B4%C1%BB%FA&q=CGI&cond=1&logs=10&sort=1 日付が「日付 : 2014/05/27(Tue) 06:17:11」と時間まで表示されているのですが、 これを「日付 : 2014/05/27(Tue) 」と日付だけにしたいのです。 「ksearch.cgi」の # 結果 my $i = $pg; my $body; foreach (@log) { my ($page,$ttl,$time,$wd,$bk,$nx,$yyyymmdd,$year) = split(/\t/); $i++; my $tmp = $loop; $tmp =~ s/!num!/$i/g; $tmp =~ s/!title!/$ttl/g; $tmp =~ s/!url!/$url$page/g; $tmp =~ s|!doc!|$bk<b>$wd</b>$nx|g; $tmp =~ s/!date!/&date($time)/eg; $body .= $tmp; !date!のあたりをいじればいいんだろうと思っていろいろやりましたが、 ページを更新した日付になってくれません。 どうしたらできるでしょうか…

    • ベストアンサー
    • CGI