重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

【GOLF me!】初月無料お試し

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

A 回答 (1件)

よく使われる手法は、


・1つのデータはハッシュ(連想配列)で定義する
・ハッシュのリファレンスを配列で扱う
というものです。(あくまで1例です。)

例えばファイルに、1データ1行・項目カンマ区切りで「商品名」「価格」「残り日数」が入っている場合、
  my @item;
  open FH, "item.dat";
  while (<FH>) {
    chomp;
    my ($name, $price, $days) = split /,/;
    push @item, {name=>$name, price=>$price, days=>$days};
  }
  close FH;
として商品のリストを生成します。

また、前提として $FORM{sort} にソートする項目が入っているとします。
(値は、name price days のいずれかとします。)
同じく、$FORM{order} にソートオーダ(昇順・降順)を示すデータが入っているとします。
(値は、up down のいずれかとします。)

項目ごとに比較の仕方(数値比較か文字列比較か)が異なるので、ソート項目及びオーダごとの比較関数が必要になります。
各関数のリファレンスを $FORM{sort} と $FORM{order} をキーとするハッシュに入れておけば、ソートを行う部分がすっきりと書けます。

まずは比較関数の定義部
  my %fn_sort = (
    'name-up'  => sub {$a->{name} cmp $b->{name}},
    'name-down' => sub {$b->{name} cmp $a->{name}},
    'price-up'  => sub {$a->{price} <=> $b->{price}},
    'price-down' => sub {$b->{price} <=> $a->{price}},
    'days-up'  => sub {$a->{days} <=> $b->{days}},
    'days-down' => sub {$b->{days} <=> $a->{days}},
  );
次にソートを行う部分
  @item = sort { $fn_sort{"$FORM{sort}-$FORM{order}"}->() } @item;

$FORM{sort} や $FORM{order} に正常な値が入っていないと実行エラーとなるので、デフォルト設定などをして下さい。
    • good
    • 0
この回答へのお礼

詳細な解説ありがとうございました。
リファレンスは扱ったことがなかったため、勉強してみようと思います。混乱していた考えにだいぶ方向性が見えてきました。感謝いたします。

お礼日時:2003/02/03 18:16

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!