Perlでのハッシュのソートについてのメモです。普段よくやってるはずなんですが、それでもど忘れしてしまうので。
Perlのハッシュは作成時のキー順はまったく保証されないので、並び替えする場合はキーか値のどちらかの配列をソートして使用します。
キーでソートする
sort
演算子を使います。keys
でキーの配列を得てソートした結果を受け取ります。
my %score = ( 'い' => 1080, 'ろ' => 216, 'は' => 324 );
my @members = sort { $a cmp $b } keys %score;
print "content-type: text/plain; charset=utf8\n\n";
print "メンバー一覧\n";
for my $name ( @members ) {
print "$name: $score{$name}\n";
}
> メンバー一覧 > い: 1080 > は: 324 > ろ: 216
値でソートする
同じくsort
を使って、並び替えられた結果のキーの配列を受け取ります。比較を値で行ないます。数値での比較にはスペースシップ演算子(<=>
)を使います。また、得点ランキングとして大きい数字が最初に来るように$b <=> $a
($a
と$b
を逆に)としています。
my %score = ( 'い' => 1080, 'ろ' => 216, 'は' => 324 );
my @winners = sort { $score{$b} <=> $score{$a} } keys %score;
print "content-type: text/plain; charset=utf8\n\n";
print "得点ランキング\n";
for my $name ( @winners ) {
print "$name: $score{$name}\n";
}
> 得点ランキング > い: 1080 > は: 324 > ろ: 216
同点者がいた場合は、キー名順にならべるように追加したところ。sort
では$a
と$b
が同点だった場合は0
が返ります。同点だった場合はキー名を文字列でソートします。
...
$score{'や'} = 1080;
@winners = sort { $score{$b} <=> $score{$a} or $a cmp $b } keys %score;
print "得点ランキング\n";
for my $name ( @winners ) {
print "$name: $score{$name}\n";
}
> 得点ランキング > い: 1080 > や: 1080 > は: 324 > ろ: 216
値がリファレンスの場合のソート
値がハッシュリファレンス、という程度ならボクでも簡単です。
...
my %members = (
'い' => { 'score' => 1080, 'age' => 30 },
'ろ' => { 'score' => 216, 'age' => 25 },
'は' => { 'score' => 324, 'age' => 18 },
'や' => { 'score' => 1080, 'age' => 60 }
);
@winners = sort { $members{$b}->{'score'} <=> $members{$a}->{'score'} or $a cmp $b } keys %members;
print "得点ランキング\n";
for my $name ( @winners ) {
print "$name: ${members{$name}->{'score'}}\n";
}
> 得点ランキング > い: 1080 > や: 1080 > は: 324 > ろ: 216