如何对 Perl 哈希值进行排序并相应地对键进行排序(可能在两个数组中)?
Posted
技术标签:
【中文标题】如何对 Perl 哈希值进行排序并相应地对键进行排序(可能在两个数组中)?【英文标题】:How can I sort a Perl hash on values and order the keys correspondingly (in two arrays maybe)? 【发布时间】:2012-06-09 16:38:56 【问题描述】:在 Perl 中,我想按数值对哈希的键进行排序:
five => 5
ten => 10
one => 1
four => 4
产生两个数组:
(1,4,5,10) and (one, four, five, ten)
然后我想规范化 values 数组,使数字是连续的:
(1,2,3,4)
我该怎么做?
【问题讨论】:
【参考方案1】:首先按关联的值对键进行排序。然后获取值(例如通过使用哈希切片)。
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;
【讨论】:
这很容易。有时很难想出那些漂亮的捷径。谢谢池上。 您可以在sort function in Perl查看更多信息【参考方案2】:如何对散列进行排序(可选择按值而不是键)?
要对哈希进行排序,请从键开始。在此示例中,我们将键列表提供给排序函数,然后按 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;
【讨论】:
Nit:lc($a) cmp lc($b)
,你也写成 "\L$a" cmp "\L$b"
,不会总是做正确的事。你想要fc($a) cmp fc($b)
("\F$a" cmp "\F$b"
)。从 5.16 开始提供。【参考方案3】:
请参阅标题为“How do I sort a hash (optionally by value instead of key)”的 Perl 常见问题解答条目。
您也可以使用perldoc -q
在您的计算机上本地搜索常见问题解答,如perldoc -q sort
,这是我找到您的答案的方式。
【讨论】:
【参考方案4】:my ( @nums, @words );
do push @nums, shift @$_;
push @words, shift @$_;
foreach sort $a->[0] <=> $b->[0]
map [ $h-> $_ , $_ ] keys %$h
;
【讨论】:
@Moni,它工作得很好,按原样编写。如果您需要%h
,那么地图中只有keys %h
和$h $_
。
解释一下。例如,想法是什么?以上是关于如何对 Perl 哈希值进行排序并相应地对键进行排序(可能在两个数组中)?的主要内容,如果未能解决你的问题,请参考以下文章