sort LIST

In list context, this sorts the LIST and returns the sorted list value. In scalar context, the behaviour of sort is undefined.

リストコンテキストでは、LIST をソートし、ソートされたリスト値を返します。 スカラコンテキストでは、sort の振る舞いは未定義です。

If SUBNAME or BLOCK is omitted, sorts in standard string comparison order. If SUBNAME is specified, it gives the name of a subroutine that returns an integer less than, equal to, or greater than 0, depending on how the elements of the list are to be ordered. (The <=> and cmp operators are extremely useful in such routines.) SUBNAME may be a scalar variable name (unsubscripted), in which case the value provides the name of (or a reference to) the actual subroutine to use. In place of a SUBNAME, you can provide a BLOCK as an anonymous, in-line sort subroutine.

SUBNAME や BLOCK を省略すると、sort は標準の 文字列比較の順番で行なわれます。 SUBNAME を指定すると、それは、リストの要素をどのような順番に並べるかに 応じて、負の整数、0、正の整数を返すサブルーチンの名前であると解釈されます。 (このようなルーチンには、<=> 演算子や cmp 演算子が、 たいへん便利です。) SUBNAME は、スカラ変数名(添字なし)でもよく、その場合には、その値が使用する 実際のサブルーチンの名前(またはそのリファレンス)と解釈されます。 SUBNAME の代わりに、無名のインラインソートルーチンとして、BLOCK を 書くことができます。

If the subroutine's prototype is ($$), the elements to be compared are passed by reference in @_, as for a normal subroutine. This is slower than unprototyped subroutines, where the elements to be compared are passed into the subroutine as the package global variables $a and $b (see example below). Note that in the latter case, it is usually highly counter-productive to declare $a and $b as lexicals.

サブルーチンのプロトタイプが ($$)の場合、比較する要素は通常のサブルーチンと 同じように @_ の中にリファレンスとして渡されます。 これはプロトタイプなしのサブルーチンより遅いです; この場合は比較のため サブルーチンに渡される二つの要素は、パッケージのグローバル変数 $a$b で渡されます(次の例を参照してください)。 後者の場合、レキシカルに $a$b を宣言するのは普通とても 逆効果になります。

If the subroutine is an XSUB, the elements to be compared are pushed on to the stack, the way arguments are usually passed to XSUBs. $a and $b are not set.

サブルーチンが XSUB の場合、比較される要素は、普通に引数を XSUB に渡す形で、 スタックにプッシュされます。 $a$b は設定されません。

The values to be compared are always passed by reference and should not be modified.


You also cannot exit out of the sort block or subroutine using any of the loop control operators described in perlsyn or with goto.

また、ソートブロックやサブルーチンから perlsyn で説明されている ループ制御子や goto を使って抜けてはいけません。

When use locale (but not use locale ':not_characters') is in effect, sort LIST sorts LIST according to the current collation locale. See perllocale.

use locale が有効(そして use locale ':not_characters' が 有効でない)の場合、sort LIST は LIST を現在の比較ロケールに従って ソートします。 perllocale を参照してください。

sort returns aliases into the original list, much as a for loop's index variable aliases the list elements. That is, modifying an element of a list returned by sort (for example, in a foreach, map or grep) actually modifies the element in the original list. This is usually something to be avoided when writing clear code.

sort は元のリストへのエイリアスを返します; for ループのインデックス変数がリスト要素へのエイリアスと同様です。 つまり、sort で返されるリストの要素を(例えば、 foreachmapgrep で)変更すると、実際に元のリストの要素が 変更されます。 これはきれいなコードを書くときには普通は回避されます。

Perl 5.6 and earlier used a quicksort algorithm to implement sort. That algorithm was not stable and could go quadratic. (A stable sort preserves the input order of elements that compare equal. Although quicksort's run time is O(NlogN) when averaged over all arrays of length N, the time can be O(N**2), quadratic behavior, for some inputs.) In 5.7, the quicksort implementation was replaced with a stable mergesort algorithm whose worst-case behavior is O(NlogN). But benchmarks indicated that for some inputs, on some platforms, the original quicksort was faster. 5.8 has a sort pragma for limited control of the sort. Its rather blunt control of the underlying algorithm may not persist into future Perls, but the ability to characterize the input or output in implementation independent ways quite probably will.

Perl 5.6 以前ではソートの実装にクイックソートアルゴリズムを使っていました。 このアルゴリズムは安定しておらず、2 乗の時間が掛かる 可能性があります。 (安定した ソートは、比較した時に同じ要素の入力順が保存されます。 クイックソートの実行時間は、長さ N の全ての配列の平均では O(NlogN) ですが、 入力によっては O(N**2) という 2 乗の 振る舞いをすることがあります。) 5.7 では、クイックソートによる実装は、最悪の場合の振る舞いも O(NlogN) である、 安定したマージソートアルゴリズムに置き換えられました。 しかし、入力とプラットフォームによっては、ベンチマークはクイックソートの方が 速くなります。 5.8 ではソートを限定的に制御できる sort プラグマがあります。 この、アルゴリズムの直接的な制御方法は将来の perl では引き継がれないかも しれませんが、実装に依存しない形で入力や出力を性格付ける機能は おそらくあります。



    # sort lexically
    my @articles = sort @files;

    # same thing, but with explicit sort routine
    my @articles = sort {$a cmp $b} @files;

    # now case-insensitively
    my @articles = sort {fc($a) cmp fc($b)} @files;

    # same thing in reversed order
    my @articles = sort {$b cmp $a} @files;

    # sort numerically ascending
    my @articles = sort {$a <=> $b} @files;

    # sort numerically descending
    my @articles = sort {$b <=> $a} @files;

    # this sorts the %age hash by value instead of key
    # using an in-line function
    my @eldest = sort { $age{$b} <=> $age{$a} } keys %age;

    # sort using explicit subroutine name
    sub byage {
        $age{$a} <=> $age{$b};  # presuming numeric
    my @sortedclass = sort byage @class;

    sub backwards { $b cmp $a }
    my @harry  = qw(dog cat x Cain Abel);
    my @george = qw(gone chased yz Punished Axed);
    print sort @harry;
        # prints AbelCaincatdogx
    print sort backwards @harry;
        # prints xdogcatCainAbel
    print sort @george, 'to', @harry;
        # prints AbelAxedCainPunishedcatchaseddoggonetoxyz

    # inefficiently sort by descending numeric compare using
    # the first integer after the first = sign, or the
    # whole record case-insensitively otherwise

    my @new = sort {
        ($b =~ /=(\d+)/)[0] <=> ($a =~ /=(\d+)/)[0]
                    fc($a)  cmp  fc($b)
    } @old;

    # same thing, but much more efficiently;
    # we'll build auxiliary indices instead
    # for speed
    my (@nums, @caps);
    for (@old) {
        push @nums, ( /=(\d+)/ ? $1 : undef );
        push @caps, fc($_);

    my @new = @old[ sort {
                           $nums[$b] <=> $nums[$a]
                           $caps[$a] cmp $caps[$b]
                         } 0..$#old

    # same thing, but without any temps
    my @new = map { $_->[0] }
           sort { $b->[1] <=> $a->[1]
                  $a->[2] cmp $b->[2]
           } map { [$_, /=(\d+)/, fc($_)] } @old;

    # using a prototype allows you to use any comparison subroutine
    # as a sort subroutine (including other package's subroutines)
    package Other;
    sub backwards ($$) { $_[1] cmp $_[0]; }  # $a and $b are
                                             # not set here
    package main;
    my @new = sort Other::backwards @old;

    # guarantee stability, regardless of algorithm
    use sort 'stable';
    my @new = sort { substr($a, 3, 5) cmp substr($b, 3, 5) } @old;

    # force use of mergesort (not portable outside Perl 5.8)
    use sort '_mergesort';  # note discouraging _
    my @new = sort { substr($a, 3, 5) cmp substr($b, 3, 5) } @old;

Warning: syntactical care is required when sorting the list returned from a function. If you want to sort the list returned by the function call find_records(@key), you can use:

警告: 関数からかえされたリストをソートするときには文法上の注意が必要です。 関数呼び出し find_records(@key) から返されたリストをソートしたい場合、 以下のように出来ます:

    my @contact = sort { $a cmp $b } find_records @key;
    my @contact = sort +find_records(@key);
    my @contact = sort &find_records(@key);
    my @contact = sort(find_records(@key));

If instead you want to sort the array @key with the comparison routine find_records() then you can use:

一方、配列 @key を比較ルーチン find_records() でソートしたい場合は、 以下のように出来ます:

    my @contact = sort { find_records() } @key;
    my @contact = sort find_records(@key);
    my @contact = sort(find_records @key);
    my @contact = sort(find_records (@key));

You must not declare $a and $b as lexicals. They are package globals. That means that if you're in the main package and type

$a$b をレキシカルとして宣言しては いけません。 これはパッケージグローバルです。 つまり、main パッケージで以下のように書いた場合:

    my @articles = sort {$b <=> $a} @files;

then $a and $b are $main::a and $main::b (or $::a and $::b), but if you're in the FooPack package, it's the same as typing

$a$b$main::a$main::b (または $::a$::b) を 意味しますが、FooPack パッケージ内の場合、これは以下と同じになります:

    my @articles = sort {$FooPack::b <=> $FooPack::a} @files;

The comparison function is required to behave. If it returns inconsistent results (sometimes saying $x[1] is less than $x[2] and sometimes saying the opposite, for example) the results are not well-defined.

比較関数は一貫した振る舞いをすることが求められます。 一貫しない結果を返す(例えば、あるときは $x[1]$x[2] より 小さいと返し、またあるときは逆を返す)場合、結果は未定義です。

Because <=> returns undef when either operand is NaN (not-a-number), be careful when sorting with a comparison function like $a <=> $b any lists that might contain a NaN. The following example takes advantage that NaN != NaN to eliminate any NaNs from the input list.

<=> はどちらかのオペランドが NaN (not-a-number) のときに undef を返すので、$a <=> $b といった比較関数で ソートする場合はリストに NaN が含まれないように注意してください。 以下の例は 入力リストから NaN を取り除くために NaN != NaN という性質を 利用しています。

    my @result = sort { $a <=> $b } grep { $_ == $_ } @input;