Perlでは、ハッシュのキーを値で数値的にソートしたい:
{
five => 5
ten => 10
one => 1
four => 4
}
2つの配列を生成する:
(1,4,5,10) and (one, four, five, ten)
そして、数値が連続するように値の配列を正規化したい:
(1,2,3,4)
どうすればいいですか?
最初に、関連する値でキーを並べ替えます。次に、値を取得します(たとえば、ハッシュスライスを使用して)。
my @keys = sort { $h{$a} <=> $h{$b} } keys(%h);
my @vals = @h{@keys};
または、ハッシュ参照がある場合。
my @keys = sort { $h->{$a} <=> $h->{$b} } keys(%$h);
my @vals = @{$h}{@keys};
ハッシュをソートする方法(オプションでキーではなく値で)
ハッシュをソートするには、キーから始めます。この例では、キーのリストをソート関数に渡し、ソート関数はそれらをASCIIbeticallyに比較します(ロケール設定によって影響を受ける可能性があります)。出力リストには、ASCII順のキーがあります。キーを取得したら、それらを調べて、キーをASCII順でリストするレポートを作成できます。
my @keys = sort { $a cmp $b } keys %hash;
foreach my $key ( @keys ) {
printf "%-20s %6d\n", $key, $hash{$key};
}
ただし、sort()ブロックの方がより凝っています。キーを比較する代わりに、キーを使用して値を計算し、その値を比較として使用できます。
たとえば、レポートの順序を大文字と小文字を区別しないようにするには、lcを使用して、キーを比較する前に小文字にします。
my @keys = sort { lc $a cmp lc $b } keys %hash;
注:計算が高価な場合、またはハッシュに多くの要素がある場合、シュワルツ変換を見て計算結果をキャッシュすることをお勧めします。
代わりにハッシュ値でソートする場合は、ハッシュキーを使用して検索します。キーのリストは引き続き入手できますが、今回は値によって順序付けされています。
my @keys = sort { $hash{$a} <=> $hash{$b} } keys %hash;
そこからもっと複雑になります。ハッシュ値が同じ場合、ハッシュキーで2次ソートを提供できます。
my @keys = sort {
$hash{$a} <=> $hash{$b}
or
"\L$a" cmp "\L$b"
} keys %hash;
Perl FAQ「ハッシュをソートする方法(オプションでキーではなく値で)」というタイトルのエントリを参照してください。」
http://perldoc.Perl.org/perlfaq4.html#How-do-I-sort-a-hash-%28optionally-by-value-instead-of-key%29?
perldoc -q
を使用して、perldoc -q sort
のようにFAQをローカルでマシン上で検索することもできます。
my ( @nums, @words );
do { Push @nums, shift @$_;
Push @words, shift @$_;
}
foreach sort { $a->[0] <=> $b->[0] }
map { [ $h->{ $_ }, $_ ] } keys %$h
;