perlでsort関数が理解できません!!

[上に] [前に] [次に]
ちゃいパパ [E-Mail] [HomePage] 1999/10/05(火) 17:02:44
perlで、 sort関数の使い方が(とほほさんの説明)理解できません。

@result = sort { $a <=> $b } @list;

特に $a と $b が分かりません。誰がどんな値をセットする?

また、CGI環境のsortでデータ件数が多くなるとエラーメッセージなしの
だんまり終了するみたいなのですが...。なにか分かりますか?
(他で正常のCGIがプロバイダが違うとsortでコケルみたい...)

ふじ 1999/10/05(火) 18:00:16
>特に $a と $b が分かりません。誰がどんな値をセットする?
Perlのインタプリタが、比較する2つの値(配列の要素)をセットします。
sort{ } は並べ替えるための大小比較の関数を定義するものです。

{$a <=> $b}
とすれば昇順、
{$b <=> $a}
とすれば降順になります。

また、応用として、
@name = ( 'taro', 'jiro', 'saburo', 'shiro');
%height = ( 'taro' => 176,
'jiro' => 185,
'saburo' => 160,
'shiro' => 170 );

こんなハッシュが定義されている場合に

sort { $height{$a} <=> $height{$b} } @name

とすると %height の値によってソートされて、
('saburo', 'shiro', 'taro', 'jiro')
という配列が返ります。

ちゃいパパ [HomePage] 1999/10/05(火) 18:22:03
ふじさん、ありがとうございました。
理解できました!!
それにちょうど、ハッシュ定義のsortのところだったので、助かりました!!

あと、下記の件、誰かこころあたりありませんか?

>CGI環境のsortでデータ件数が多くなるとエラーメッセージなしの
>だんまり終了するみたいなのですが...。なにか分かりますか?
>(他で正常のCGIがプロバイダが違うとsortでコケルみたい...)

アトム 1999/10/05(火) 19:12:20
>だんまり終了するみたいなのですが
配列のデータが全て文字ではないでしょうか?
上記の方法は数値を数値順にソートする方法です。

ふじさんが回答して下さってるので、理解されたかも
知れませんが、復習も兼ねて、

sortには3つの構文があります。
1:sort LIST
2:sort SUBNAME LIST
3:sort BLOCK LIST
の3つです。
一番目は比較的簡単な用法です。
例えば、
@list = (0,1,2,3,4,5,6,7,8,9,10,11,12);
の時、
@result = sort @list;
とすると、@kekkalistには、
(0,1,10,11,12,2,3,  ,9)となります。

これを数値の値順にしたいときに2番目と3番目の構文を使います。
まず、2番目の構文を使う場合、二つの数値を比較する次のようなサブルーチンが必要になります。

sub number {
  if ($a < $b) {
    return -1;
  } elsif ($a == $b) {
    return 0;
  } elsif ($a > $b) {
    return 1;
}
}
ただこのサブルーチンは、記述が長くて面倒なので、そこで便利な「 <=> 」という演算子を使うと次のように簡単に記述する事ができます。

sub number {
$a <=> $b;
}
スッキリしましたね。
さて、このサブルーチンを利用してsortの第2の構文を使い、
@result = sort number @list;
と記述します。これで@kekkalistには、
(1,2,3,4,5,6,7,8,9,10,11,12)というリストになります。

プリグラム中でこのようなソートを複数回使うのなら、サブルーチンもいいのですが、
一度しか使わないなら、sortの3番目の構文を使ってサブルーチンの定義をしなく
て済みます。次のように記述します。

@result = sort {$a <=> $b } @list;


>だんまり終了するみたいなのですが
リストのデータが全て「文字」ではないでしょうか?(例えば「a」とか「1b」とか)
文字は数値として評価するとすべて「0」になります。したがって結果として
ソートが行われなかったように見えます。(上記の第1の構文を使えばASCII順
にソートしてくれます。)

参考までに、
@result = sort {($a <=> $b) || ($a cmp $b)} @list;
とすると、数値順ASCII順にソートします。(たぶん(^_^;)

ちゃいパパ [HomePage] 1999/10/06(水) 09:27:47
アトムさん、大変よくわかりました。ありがとうございました。

だんまり終了の件ですが、実は、同じデータ同じCGIで現象が違うんです。
プロバイダではデータ数が約85件まではソートしますが、これ以上だとダンマリ
終了になります。会社のCGI環境だと120件で全く問題ありません。
また、オリジナルのダウンロード元では1000件以上でソートされています。

ちなみに、現象は、私のHPのトップページのホームページPRコーナーの
"人気ランキング of ちゃいちゃんナビ"をクリックすると分かります。
(80件ぐらいの時は問題なくランキングを表示していました。)
私が思うには、プロバイダのCGI環境の何かの制限かなぁ...。
っということで、こころあたりのある方、よろしくお願い致します。

ちゃいパパ [HomePage] 1999/10/18(月) 15:14:27
[[解決]]
プロバイダ(parkcity)問い合わせたところ、やはり、
ユーザ単位にリソース(CPU パワー, 使用メモリーなど)を制限しているとのことで、
詳細は規約上、教えられないそうです。

っということで、ランキング機能はあきらめます。
みなさん、お騒がせしました。

B-Cus 1999/10/18(月) 18:44:10
> 詳細は規約上、教えられないそうです。
ちなみに、UNIX なら limits コマンドでわかるかもね。
 % /usr/bin/limits
 Resource limits (current):
    cputime          infinity secs
    filesize         infinity kb
    datasize-cur        22528 kb
    stacksize-cur        8192 kb
    coredumpsize     infinity kb
    memoryuse-cur       30720 kb
    memorylocked-cur    10240 kb
    maxprocesses-cur       64
    openfiles-cur          64

[上に] [前に] [次に]