早速、コメントありがとうございます。
On Fri, 02 Jan 2004 05:11:04 +0900
dune <FZH01112@...> さんwrote:
> 藤岡和夫 さんの [TSfree:586] Re: 欄区切りのソート から
> >#mlsort.pl
> >$/="";$lnum = shift;
> >while(<>){
> > ($mlr{(split(/\n/))[$lnum - 1]} = $_) =~ s/\n*\Z/\n\n/;
> >}
> >foreach $key (sort keys(%mlr)){
> > print $mlr{$key};
> >}
>
> これだと同じキーがあったときにデータが上書きされてしまうので、
> 厳密には while ブロックの中で if(exists $mlr{...}){...} とか
> やる必要があります。でもこの手の問題は深く考えずに Scwartz
> 変換にもっていくのが定石でしょう。
あっ、そうですね(^^;)そのSchwartz変換とか、Guttman-Rosler 変換というの
は、どのような原理なのでしょうか。
僕は日常的には連想配列に同一のキーがあるときは、一つのキーにタブかなに
かで挟んで、どんどん値を集めちゃって、後から処理しています。まあ、連想配
列のキーにはユニークなものを使うことがよいわけですけど、現実はそう甘くあ
りませんね。
>
> ソートに使うフィールドが1個だけなら、
>
> --^mlsort2.pl
> use strict;
> $/ = "";
> my $lnum = $ARGV[0] || 0;
> print grep{ s/\A.+\n// }
> sort
> map{ s/\n*\Z// and (split m/\n/)[$lnum]."\n$_\n\n" } <STDIN>;
> --$
>
> 複数あるなら
>
> --^mlsort3.pl
> use strict;
> $/ = "";
> my $lnum = $ARGV[0] || 0;
> print map{ $_->[0]."\n\n" }
> sort{ $a->[1] cmp $b->[1] or $a->[2] cmp $b->[2] or ... } # ※
> map{ s/\n*\Z// and [$_,(split m/\n/)[@ARGV]] } <STDIN>;
> --$
> ※)もっとマトモな解を募集
>
> フィールドが複数あって優先順位があって昇順・降順、辞書順・数
> 値順、という話になったらやっぱり use Sort::Fields; かな。
sortの手順は、コマンドラインで何か指定して、それに基づいてソートの手順
のサブルーチンを生成するような話になるのかもしれませんね。
しかし、そんなややこしいことをやっているとSort::Fieldsを再発明すること
になるのかな。
藤岡 和夫
FGALTS@...
kazuf@...
TS Networkのために http://homepage1.nifty.com/kazuf/