From: matz / netlab.co.jp (Yukihiro Matsumoto)
Subject: [ruby-list:8029] ruby book (Re:  Re: Dir.open order)
Date: Wed, 20 May 1998 12:54:05 +0900

> In message "[ruby-list:8028] Re: Dir.open order"
>     on 98/05/20, Kikutani Makoto <kikutani / debian.or.jp> writes:
> 
> |> 慣れて下さい.これがRuby流です.
> |
> |こういうのがRuby本に満載ですね(^^)。
> 
> そうなると良いですねえ.まだTipsに関する章(6章)は書いてない
> ので,ナニが載るのかはっきりしたことは言えないのですが.

もしこの手法を載せるとした時の為に、ちょっと書きます。

えっと、本質的に同じ手法がperl5.004添付のドキュメントperlfaq4.podの
「How do I sort an array by (anything)?」に書かれてます。当然collectで
はなくてmapを使うんですが。

			:
       If you have a complicated function needed to pull out the
       part you want to sort on, then don't do it inside the sort
       function.  Pull it out first, because the sort BLOCK can
       be called many times for the same element.  Here's an
       example of how to pull out the first word after the first
       number on each item, and then sort those words case-
       insensitively.

           @idx = ();
           for (@data) {
               ($item) = /\d+\s*(\S+)/;
               push @idx, uc($item);
           }
           @sorted = @data[ sort { $idx[$a] cmp $idx[$b] } 0 .. $#idx ];

       Which could also be written this way, using a trick that's
       come to be known as the Schwartzian Transform:

           @sorted = map  { $_->[0] }
                     sort { $a->[1] cmp $b->[1] }
                     map  { [ $_, uc((/\d+\s*(\S+)/ )[0] ] } @data;
			:

書かれているように、Perl communityではこの手法に Schwartzian Transform 
という名前がついていて、たまにcomp.lang.perl.miscでこういう話題の時に
使われてます。

--
			   稲葉 浩人 (inaba / st.rim.or.jp)