作者: 藤岡和夫
日時: 2004/1/02(10:17)
早速、コメントありがとうございます。

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/