sort関数 - 配列の並べ替え
配列を並べ替えるにはsort関数を使用します。第1引数には比較のためのコードブロックを渡します。昇順で並べ替える場合は$aを$bより先に記述し、降順で並べ替えるには$bを$aより先に記述します。比較演算子には数値として比較したい場合は<=>を使用し、辞書順で比較したい場合はcmpを使用します。コードブロックの直後にカンマがないことに注意してください。
# 昇順で並べ替え @sorted = sort { $a 演算子 $b } @array; # 降順で並べ替え @sorted = sort { $b 演算子 $a } @array;
並び替えのサンプル
数値の昇順で並べ替えるサンプルです。@numsは(2, 3, 5, 11)になります。
# 数値の昇順で並び替え my @nums = (5, 11, 3, 2); @nums = sort {$a <=> $b} @nums;
数値の降順で並べ替えるサンプルです。@numsは(11, 5, 3, 2)になります。
# 数値の降順で並び替え my @nums = (5, 11, 3, 2); @nums = sort {$b <=> $a} @nums;
辞書順の昇順で並べ替えるサンプルです。@numsは(11, 2, 3, 5)になります。11と3は辞書順で比較すると11のほうが先にきます。
# 辞書順の昇順で並び替え my @nums = (5, 11, 3, 2); @nums = sort {$a cmp $b} @nums;
辞書順の降順で並べ替えるサンプルです。@numsは(5, 3, 2, 11)になります。
# 辞書順の降順で並び替え my @nums = (5, 11, 3, 2); @nums = sort {$b cmp $a} @nums;
コードブロックの省略
コードブロックを省略した場合は辞書順の昇順で並べ替えた場合と同じ意味になります。
# 次の二つは同じ意味 @nums = sort @nums; @nums = sort {$a cmp $b} @nums;
複数条件での並び替え
文字列の長さが長い順で並び替えて、長さが同じときは辞書順の昇順で並べ替えるようにしてみます。ふたつ目の条件を指定するときは||を使用します。最初の比較で並び順を確定できなかった場合に次の比較が行われます。@strsは('aaa', 'bbb', 'aa', 'bb', 'a', 'b')になります。
my @strs = ('aaa', 'bbb', 'b', 'a', 'aa', 'bb'); @strs = sort { length $b <=> length $a || $a cmp $b } @strs;
ハッシュの値をキーで並べ替えて出力
ハッシュをキーで並べ替えて出力してみます。ハッシュはキーの順序が保障されないので、決まった並び順で出力したい場合はキーを並び替えて出力します。
my %points = (Tom => 100, Mike => 30, Mami => 90); for my $name (sort keys %points) { print "$name:$points{$name}\n"; }
配列のリファレンスの並べ替え
配列のリファレンスを並べ替えてみます。sort関数に渡すときにデリファレンスして、受け取るときもデリファレンスするのがポイントです。
my $nums = [5, 11, 3, 2]; @$nums = sort @$nums;
ハッシュの配列を並べ替える
ハッシュの配列を並べ替えてみます。サンプルのハッシュの配列には複数の人の情報が入っています。これを人物の年齢で並べ替えてみます。(注意: ハッシュの配列と呼んでいますがここでの正確な意味はハッシュのリファレンスを含む配列のリファレンスのことです。)
$aと$bにはハッシュのリファレンスが代入されてくるので、年齢を取得するには$a->{age}, $b->{age}とします。これを使用して比較を行います。
# 人物のデータ my $persons = [ {name => 'Ken', age => 19}, {name => 'Taro', age => 9}, {name => 'Kaori', age => 23} ]; @$persons = sort { $a->{age} <=> $b->{age} } @$persons;
$personsは年齢の昇順で並べ替えられて次のようなデータになります。
[ {name => 'Taro', age => 9}, {name => 'Ken', age => 19}, {name => 'Kaori', age => 23} ];