如何对值进行Perl哈希排序并相应地对键排序(可能是在两个数组中)?

如何对值进行Perl哈希排序并相应地对键排序(可能是在两个数组中)?,perl,sorting,hash,perl-hash,Perl,Sorting,Hash,Perl Hash,在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}键(%h); my@vals=@h{

在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}键(%h);
my@vals=@h{@keys};
或者如果你有一个散列引用

my @keys = sort { $h->{$a} <=> $h->{$b} } keys(%$h);
my @vals = @{$h}{@keys};
my@keys=sort{$h->{$a}$h->{$b}键(%$h);
my@vals=@{$h}{@keys};
my(@nums,@words);
执行{push@nums,shift@$};
按@words,shift@$;
}
foreach排序{$a->[0]$b->[0]}
映射{[$h->{$\},$\]}键%$h
;

请参阅标题为“”的Perl常见问题解答条目


您还可以使用
perldoc-q
在您的计算机上本地搜索常见问题,如
perldoc-q sort
,这就是我如何找到答案的方法。

如何对哈希进行排序(可以选择按值而不是键)?

要对哈希进行排序,请从键开始。在本例中,我们给出了排序函数的键列表,然后排序函数会对它们进行逻辑比较(这可能会受到您的区域设置的影响)。输出列表中的键按逻辑顺序排列。一旦我们有了密钥,我们就可以通过它们来创建一个报告,该报告按逻辑顺序列出密钥

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}}keys%hash;
从那里我们可以变得更复杂。如果散列值相同,我们可以对散列键进行二次排序

my @keys = sort {
$hash{$a} <=> $hash{$b}
or
"\L$a" cmp "\L$b"
} keys %hash;
my@keys=sort{
$hash{$a}$hash{$b}
或
\L$a“cmp”\L$b
}密钥%hash;

这很容易。有时候很难想出那些好的捷径。谢谢ikegami。你可以在@Moni中看到更多信息,它工作得很好,按原样编写。如果您需要
%h
,那么它只是地图中的
键%h
$h{$}
。应该有一个解释。例如,这个想法是什么?Nit:
lc($a)cmp-lc($b)
,您也将其写成了
“\L$a“cmp”\L$b”
,它并不总是做正确的事情。您需要
fc($a)cmp-fc($b)
“\F$a”cmp“\F$b”
)。从5.16开始提供。
my @keys = sort { $hash{$a} <=> $hash{$b} } keys %hash;
my @keys = sort {
$hash{$a} <=> $hash{$b}
or
"\L$a" cmp "\L$b"
} keys %hash;