質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.61%

  • Perl

    451questions

    Perlは多目的に使用される実用性が高い動的プログラミング言語のひとつです。

perl 検索結果をsort関数で降順にしたい

受付中

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 118

pyoo001213

score 5

http://www.japor.or.jp/search/

上記のサイトを10年以上前に作成されたプログラムです。
作成者が身体を崩したため私の方で更新作業をおこなっています。
現在、古い順に2000年より昇順で表示されるように作成をしているのですが、新しい順(降順)にする場合はどのようなプログラムを組めばいいのか、ネットで色々文献を調べましたが難しかったためご質問致しました。

配列を並び替えるためにsort関数を使用するまではわかってそれらしい配列にsortをかけてみたのですがうまくいきません。
念の為、htmlとcgiのプログラムを載せます。

下記プログラムのどこにsortをかければよろしいのでしょうか?
恐らく、下記のプログラム内と思い一部抜粋をいたしました。
ご教示頂ければ幸いです。

よろしくお願い致します。

#!/usr/local/bin/perl
##!c:/perl/bin/perl
#
## ===========================================================================
## データ表示部テンプレート
## ===========================================================================
# @param  : %str             対照データ
# @return : $str
# ---
# @sub    : str_midasi     ( yoron_indexA_htm.tmp )
#
sub yoron_index_table_body1(){
    my ($i,$keisai_midasi,%str) = @_;
    my $str;
    # 変数作成
    my $kaisi = $str{'kikan_y'}."/".$str{'kikan_sm'}."/".$str{'kikan_sd'} if $str{'kikan_y'} ne '' || $str{'kikan_sm'} ne '' || $str{'kikan_sd'} ne '' ;
    $str{'kikan_y'}++ if $str{'kikan_sm'} > $str{'kikan_lm'};
    my $syuryo = $str{'kikan_y'}."/".$str{'kikan_lm'}."/".$str{'kikan_ld'} if $str{'kikan_lm'} ne '' || $str{'kikan_ld'} ne '' ;
    $kaisi =~ s/\/+$//;
    $syuryo =~ s/\/+$//;
    my $kikan = $kaisi;
    #print "$syuryo<br>";
    $kikan .= "~ $syuryo" if $syuryo ne "";
    $kikan = '&nbsp;' if $kikan eq '';

    $str{'sampling'} = '-' if $str{'sampling'} eq "";
    $str{'syutai'} = '&nbsp;' if $str{'syutai'} eq "";
    $str{'taosyou'} = '&nbsp;' if $str{'taisyou'} eq "";
    $str{'houhou'} = '-' if $str{'houhou'} eq "";
    $str{'sample'} = '&nbsp;' if $str{'sample'} eq "";
    $str{'kaisyu'} = '&nbsp;' if $str{'kaisyu'} eq "";
#$str = qq(<TABLE BORDER="1" CELLSPACING="1" CELLPADDING="1" WIDTH="700">\n);
$str = qq(<TABLE BORDER="1" CELLSPACING="1" CELLPADDING="1" WIDTH="640">\n);
$str .= qq(  <TR>\n);
$str .= qq(    <TD ALIGN="center" WIDTH="180" ROWSPAN="2" COLSPAN="2" BGCOLOR="#C0FFC0"><FONT>$str{'syutai'}</FONT></TD>\n);
#$str .= qq(    <TD ALIGN="center" WIDTH="200" ROWSPAN="2" COLSPAN="2" BGCOLOR="#C0FFC0"><FONT>$str{'syutai'}</FONT></TD>\n);
$str .= qq(    <TD ALIGN="center" WIDTH="100" ROWSPAN="2" > $kikan </TD>\n);
$str .= qq(    <TD ALIGN="center" WIDTH="100" ROWSPAN="2">$str{'taisyou'}</TD>\n);
$str .= qq(    <TD ALIGN="center" WIDTH="100" BGCOLOR="#FFFFC0">$str{'houhou'}</TD>\n);
$str .= qq(    <TD ALIGN="center" WIDTH="80" ROWSPAN="2">$str{'sample'}</TD>\n);
$str .= qq(    <TD ALIGN="center" WIDTH="80" ROWSPAN="2">$str{'kaisyu'}</TD>\n);
$str .= qq(  </TR>\n);
$str .= qq(  <TR>\n);
$str .= qq(    <TD ALIGN="center" WIDTH="100" BGCOLOR="#FFFFC0">$str{'sampling'}</TD>\n);
$str .= qq(  </TR><TR><TD COLSPAN="7">\n);


$str .= qq(<TABLE BORDER="0" CELLSPACING="3" CELLPADDING="3" WIDTH="640">\n);
#$str .= qq(<TABLE BORDER="0" CELLSPACING="3" CELLPADDING="3" WIDTH="680">\n);
#$str .= qq(<TR>\n);
$str .= qq(    $keisai_midasi\n);
#$str .= qq(</TR>\n);
$str .= qq(</TABLE>\n);
$str .= qq(\n);
$str .= qq(</TR></TD>\n);

$str .= qq(</TABLE>\n);
#$str .= qq(<HR WIDTH="700" ALIGN="LEFT">\n);




#$str .= qq(  <TABLE BORDER="1" CELLSPACING="1" CELLPADDING="1" WIDTH="700">\n);
#$str .= &str_midasi;
#$str .= qq(    <TR> \n);
#$str .= qq(      <TD WIDTH="80" ALIGN="center" VALIGN="middle" rowspan="2">$kaisi&nbsp;</TD>\n);
#$str .= qq(      <TD WIDTH="80" ALIGN="center" VALIGN="middle" rowspan="2">$syuryo&nbsp;</TD>\n);
#$str .= qq(      <TD WIDTH="100" ALIGN="center" VALIGN="middle" BGCOLOR="#E0FFE0" rowspan="2">$str{'happyou'}&nbsp;</TD>\n);
#$str .= qq(      <TD WIDTH="90" ALIGN="left" VALIGN="middle" BGCOLOR="#E0FFE0" rowspan="2">$str{'syutai'}&nbsp;</TD>\n);
#$str .= qq(      <TD WIDTH="90" ALIGN="left" VALIGN="middle" rowspan="2">$str{'taisyou'}&nbsp;</TD>\n);
#$str .= qq(      <TD WIDTH="90" ALIGN="center" VALIGN="middle" BGCOLOR="#FFFFC0">$str{'houhou'}&nbsp;</TD>\n);
#$str .= qq(      <TD WIDTH="90" ALIGN="right" VALIGN="middle" rowspan="2">$str{'sample'}&nbsp;</TD>\n);
#$str .= qq(      <TD WIDTH="80" ALIGN="right" VALIGN="middle" rowspan="2">$str{'kaisyu'}&nbsp;</TD>\n);
#$str .= qq(    </TR>\n);
#$str .= qq(    <TR>\n);
#$str .= qq(      <TD WIDTH="90" ALIGN="center" VALIGN="middle" BGCOLOR="#FFFFC0">  $str{'sampling'} &nbsp;</TD>\n);
#$str .= qq(    </TR>\n);
#$str .= qq(  </TABLE>\n);
return $str;

}
## ===========================================================================
## 見出し部分テンプレート(検索結果内)
## ===========================================================================
sub str_midasi{
    my %str = @_;
    my $midasi ;
    my $key;
    $midasi = "";

    for ($i = 1;$i < 11;$i++){
        $key = "midasi$i";
        next if $str{$key} eq "";
        $midasi .= $str{$key}."<br>\n";
    }
    $midasi =~ s/<BR>\n$/\n/i;
    $str{'happyou'} = '&nbsp' if $str{'happyou'} eq '';
    $midasi = qq{<TD WIDTH="540" BGCOLOR="#FFFFF0">$midasi</TD>\n};
#    $midasi = qq{<TD WIDTH="580" BGCOLOR="#FFFFF0">$midasi</TD>\n};
    #$midasi .= qq{</TR><TR>\n};
    $keisai = qq{<TD ALIGN="center" BGCOLOR="#FFFFC0" NOWRAP WIDTH="100" COLSPAN="2">$str{'happyou'}</TD>\n}.$midasi;

    return $keisai;
}



▼cgi

## ----------------------------------------------------#
## make_out_dat
## データをフィルタにかけ、検索全件数の設定
## 調査主体で5件 の 出力件数を出力用ハッシュに入れる
## ----------------------------------------------------#
## @param  : なし
## @grobal : hash %{out -> {データ数}}
## @grobal : $all_dat
## @grobal : $next_num
## @return : 1(なし)
## ---
## @sub    : check_cond      ( this_script )
sub make_out_dat(){
    my $flag;
    my $i = 0;
    my $j = 0;
    my $chosa_no = "";
    my $chosa_bk = "";

    # ページをチェックし、表示開始・衆力件数を設定
    $in{'p'} =0 unless defined $in{'p'};
    my $str_num = $in{'p'} * $hyouzi_num;
    my $lst_num = $str_num + $hyouzi_num;

    # データをフィルタに書け、表示分のみをハッシュに入れる
    $j = 0;
    for (@$input ){
        $j++;
        # フィルター
        $flag = &check_cond(%{$_}) if $in{'t'} eq "check";
        next if $flag != 0;
        $chosa_no = substr($_ -> {'chosa_no'},0,5);
        if ($chosa_no ne $chosa_bk){
            $i++;
            $chosa_bk = $chosa_no;
            $j = 0;
        }
        # 表示分のみハッシュへ
        if ($i >$str_num && $i <= $lst_num){
            $key1 = sprintf("%03d",$i);
            $key2 = sprintf("%03d",$j);
            %{$out -> {$key1."_".$key2}} = %{$_};
        }

    }
    # 全件数設定
    $all_dat = $i;
    $next_num = $all_dat - $hyouzi_num * ($in{'p'}+1) if $in{'p'} ne '';

    # [次の20件、前の20件」ボタンの作成
    $buttom1 = &last_buttom if $in{'p'} > 0;
    $buttom2 = &next_buttom if $next_num > 0;
    #$buttom = '<table><tr>'.$buttom.'</tr></table>';
    # 件数表示部分の作成
    if ($in{'t'} ne 'check' || $check_flag == 0){
        $kensuu = "<B> 全体件数:$all_dat 件 </B>\n" ;
        $javasc = qq{<A HREF="javascript:showsample();"><I>検索設定の\表\示</I></A><BR>\n};
        $comment = '検索をする場合は以下をクリックして検索条件の設定画面を表示してください';
        $zenken = "\全\件\を\表\示\し\て\い\ま\す。";
    }else{
        $kensuu = "<B>該当調査件数:$all_dat件</B>\n"  ;
        $zenken = "\検\索\結\果\を\表\示\し\て\い\ま\す。";
        $javasc = qq{<A HREF="./yoron.cgi"><I>全件\表\示</I></A><BR>\n};
        $comment = '検索条件を変更する場合は、先の検索画面を表示して検索を実行してください。';
    }
    $a = $all_dat/$hyouzi_num;
    $all_page_num = ($a == int($a) ? $a : int($a+1)) ;
    $kensuu .= "(" .($in{'p'}+1)."".$all_page_num." 頁)";
    $i = 0;
    $chosa_bk = "";
    for $str (keys %$out){
        $chosa_no = substr($out -> {$str} ->{'chosa_no'},0,5);
        if($chosa_no ne $chosa_bk){
            if ($chosa_bk ne ''){
                $result_tmp  =~ s/<\/tr><tr>\n$//;
                $result .= &yoron_index_table_body1($i,$result_tmp,%tmp); 
                $result_tmp = "";
            }
            %tmp = %{$out -> {$str}};
            $chosa_bk = $chosa_no;
            $i = 0;
        }
        $result_tmp .= "<TR>".&str_midasi(%{$out -> {$str}})."</TR>";
        $i++;

    }
    $result .= &yoron_index_table_body1($i,$result_tmp,%tmp); 

}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • KojiDoi

    2018/06/11 22:21

    質問文の中にコードを含めるときは、その前後を```で挟んでください。 https://teratail.com/questions/123033 この質問の中で、LouiS0616さんが図で分かりやすく説明されているので参考にしてください。 これにより、コード部分が視覚的に区別しやすくなり、インデントも再現され、なにより、回答者が自分の環境でコードを実行しようとするときにコピペが大変簡単になります。

    キャンセル

  • pyoo001213

    2018/06/11 22:25

    ご丁寧にありがとうございました。不慣れなもので大変申し訳ございません。

    キャンセル

回答 1

0

実際にcgiを動かしてみる気力はないので、以下は質問文中のコードをざっと見た限りでの考察です。

まず、sortをどこで実行するかですが、

 for $str (keys %$out){


からのループでデータを順番に取り出してhtmlテーブルを作っているようですので、sortをかけるならここでしょうね。まず日付によってデータの「大小」を決める「評価関数」というものを作り(たとえばby_date()とでもしておきますか)、これを使って次のような感じでソートします。

 for $str (keys sort by_date %$out){


のようになります。

評価関数とは、sort対象となる配列のの中の任意の二つの要素を比較して大小を判定するものです。perlでは次のようなお約束があります。

  1. 関数内では、比較対象の二つの要素を$a, $bとして参照する。
  2. $aの方が「大きい」なら-1、同じなら0、$bの方が「大きい」なら1と、1,0,-1の3種類の値のうちのどれかを返り値とする。

大体次のような感じになるでしょう。

sub by_date(){
  #date: "2017/5/30"

  my($ya, $ma, $da) = split("/", $a->{'date'});
  my($yb, $mb, $db) = split("/", $b->{'date'});

  return( $ya <=> $yb or $ma <=> $mb or $da <=> $db);
}


ここでは'date'というキーを仮定しましたが、この辺は元のスクリプトのハッシュの構成に適切に合わせて調整してください。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.61%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Perl

    451questions

    Perlは多目的に使用される実用性が高い動的プログラミング言語のひとつです。