CGI-BBS > CGI > Perl > Perlの設置で配列を2段階でソートできない。


カレッヂ
カレッヂ


質問者 tom  投稿日 5/3(土) 17:11:23
以前にこの掲示板でご指導頂きまして
@LIST配列の3番目を基準にソートすることが可能になりました(感謝)
一年後また悩みが出てきました。
@LIST配列を3番目でソートした内容の中で
次の優先順位として5番目でソートする事で悩んでいます。

ああああか
ああああき
ああいあか
ああいあき
ああいあく
ああいあけ
ああいあこ
ああうあか
ああうあき
ああえあこ
ああおあこ

としたいのですが下記をベースにどうすればよいのでしょうか

@tmp = map {(split /,/)[2]} @LIST;
@LIST = @LIST[sort {$tmp[$a] cmp $tmp[$b]} 0 .. $#tmp]; 

お助け下さい。

プロバイダ参照:http://www.ap-osaka.com/
サーバのOS:UNIXサーバ
パソコンのOS:WinNT系
エディタ:hidemaru
FTPソフト:FFFTP
サーバ移転:していない
改造:している 改造前正常動作
CGI習熟度:pro

回答者 まさ  [削除]  投稿日 5/4(日) 17:15:06
@dataはカンマ区切りで以下のようになっているとします。

@data = ('あ,い,う,え,お',
         'か,き,く,け,こ',
           ……  
    );

これを第3項でソートし、さらに第5項でソートするには

@data = map {$_->[0]}
            sort {$a->[3] cmp $b->[3] or $a->[5] cmp $b->[5]}
                 map {[$_, split /,/]} @data;

とします。

降順の場合は$aと$bを入れ替えて下さい。
また数字の比較は「cmp」の代わりに「<=>」を使います。

この方法は Schwartzian Transform と呼ばれているものの応用例です。

しかし例で示されいるものは Schwartzian Transform の高速版なので同じように
するには、

@tmp1 = @tmp2 = ();
foreach (@data) {
  my ($a1, $a2, $a3, $a4, $a5) = split /,/;
  push(@tmp1, $a3);
  push(@tmp2, $a5);
}
@data = @data[sort {$tmp1[$a] cmp $tmp1[$b] or
			$tmp2[$a] cmp $tmp2[$b]} 0 .. $#tmp1];

とすれば高速版になります。

質問者 tom  [削除]  投稿日 5/5(月) 12:27:39
さっそくのご指導本当に有り難うございます。すぐに試させていただきます。

このページは終了したので返信(回答)は書きこめません
 


Web裏技