( {$a <=> $b}:昇順、{$b <=> $a}:降順 )
# CSVファイルのソート例
@sort_go = sort {(split(/¥,/,$a))[4] <=> (split(/¥,/,$b))[4] || (split(/¥,/,$a))[5] <=> (split(/¥,/,$b))[5]} @sort_zen;
1:sort LIST
@list = (0,1,2,3,10,11,12);
@result = sort @list;
@resultは、(0,1,10,11,12,2,3,)となります。
2:sort SUBNAME LIST 『サブルーチンの定義あり』
sub number {
if ($a < $b) {
return -1;
} elsif ($a == $b) {
return 0;
} elsif ($a > $b) {
return 1;
}
}
sub number {
$a <=> $b; # <=> 演算子を使う場合
}
3:sort BLOCK LIST 『サブルーチンの定義なし』
@result = sort {$a <=> $b } @list;
例 ハッシュの値でソートする
@name = ('taro', 'jiro', 'saburo', 'shiro');
%height = ('taro' => 176,'jiro' => 185,'saburo' => 160,'shiro' => 170 );
sort { $height{$a} <=> $height{$b} } @name とすると %height の値でソート
例 CSVの3カラム目の情報でソート(少ない順/多い順)
@昇順 = sort { (split(/¥,/,$a))[2] <=> (split(/¥,/,$b))[2] } @hogehoge;
@降順 = reverse sort { (split(/¥,/,$a))[2] <=> (split(/¥,/,$b))[2] } @hogehoge;
(注)数値の比較は <=>、文字列の比較は cmp
例 複数キーの場合
@nums = @caps = ();
for (@old) {
push @nums, /=(¥d+)/;
push @caps, uc($_);
}
@new = @old[ sort {
$nums[$b] <=> $nums[$a]
||
$caps[$a] cmp $caps[$b]
} 0..$#old
];
# .. は範囲演算子
4:Schwartzian Transform法
効率良く複雑な条件でソートする手法。
例えばカレントディレクトリ以下のファイルを最終更新順で並べ替えるとか。
元の要素とソート条件から成る無名配列のリファレンスを作って、
ソートして並べ替えるという流れ。
# (ex) /etc/passwd をソートして出力
print map { $_->[0] }
sort {
$a->[1] <=> $b->[1] # GID
||
$a->[2] <=> $b->[2] # UID
||
$a->[3] cmp $b->[3] # login
}
map { [ $_, (split /:/)[3,2,0] ] }
`cat /etc/passwd`;
# (ex) 名前の長さで並べ替えて出力
my @list = qw(Perl Ruby JavaScript Java C++ C Python);
print join " ",
map { $_->[0] }
sort {
$b->[1] <=> $a->[1] # length
||
$a->[0] cmp $b->[0] # name
}
map { [ $_, length ] }
@list;