在 Perl 中,我想按值对哈希的键进行数字排序:
{
five => 5
ten => 10
one => 1
four => 4
}
产生两个数组:
(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};
如何对哈希进行排序(可选按值而不是键)?
要对哈希进行排序,请从键开始。在此示例中,我们将键列表提供给排序函数,然后按 ASCII 顺序比较它们(这可能会受到您的语言环境设置的影响)。输出列表具有按 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;
注意:如果计算量很大或哈希有很多元素,您可能需要查看 Schwartzian 变换来缓存计算结果。
如果我们想按哈希值排序,我们使用哈希键来查找它。我们仍然得到一个键列表,但这次它们是按它们的值排序的。
my @keys = sort { $hash{$a} <=> $hash{$b} } keys %hash;
从那里我们可以变得更复杂。如果哈希值相同,我们可以对哈希键进行二次排序。
my @keys = sort {
$hash{$a} <=> $hash{$b}
or
"\L$a" cmp "\L$b"
} keys %hash;
请参阅 Perl FAQ 条目,标题为“我如何对哈希进行排序(可选地按值而不是键) ”。
您还可以使用perldoc -q
在您的计算机上本地搜索常见问题解答,如perldoc -q sort
,这就是我找到您的答案的方式。
my ( @nums, @words );
do { push @nums, shift @$_;
push @words, shift @$_;
}
foreach sort { $a->[0] <=> $b->[0] }
map { [ $h->{ $_ }, $_ ] } keys %$h
;