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

Gog*_*ogi 23 sorting perl hash perl-hash

在Perl中,我想按值以数字方式对哈希的键进行排序:

{
  five => 5
  ten => 10
  one => 1
  four => 4
}
Run Code Online (Sandbox Code Playgroud)

生成两个数组:

(1,4,5,10) and (one, four, five, ten)
Run Code Online (Sandbox Code Playgroud)

然后我想规范化值数组,使数字是连续的:

(1,2,3,4)
Run Code Online (Sandbox Code Playgroud)

我该怎么做呢?

ike*_*ami 52

首先按关联值对键进行排序.然后获取值(例如,通过使用散列片).

my @keys = sort { $h{$a} <=> $h{$b} } keys(%h);
my @vals = @h{@keys};
Run Code Online (Sandbox Code Playgroud)

或者,如果您有哈希引用.

my @keys = sort { $h->{$a} <=> $h->{$b} } keys(%$h);
my @vals = @{$h}{@keys};
Run Code Online (Sandbox Code Playgroud)

  • 那很简单.有时很难想出那些漂亮的快捷方式.谢谢池上. (2认同)

Eri*_*ski 6

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

要对哈希进行排序,请从键开始.在这个例子中,我们给sort函数提供了一个键列表,然后以ASCII的方式比较它们(这可能会受到你的语言环境设置的影响).输出列表具有ASCIIbetical顺序的键.获得密钥后,我们可以通过它们创建一个报告,按ASCIIbetical顺序列出密钥.

my @keys = sort { $a cmp $b } keys %hash;

foreach my $key ( @keys ) {
    printf "%-20s %6d\n", $key, $hash{$key};
}
Run Code Online (Sandbox Code Playgroud)

我们可以在sort()块中获得更多的幻想.我们可以使用它们计算值并使用该值作为比较,而不是比较键.

例如,为了使我们的报表顺序不区分大小写,我们在比较它们之前使用lc来小写密钥:

my @keys = sort { lc $a cmp lc $b } keys %hash;
Run Code Online (Sandbox Code Playgroud)

注意:如果计算很昂贵或者哈希有很多元素,您可能需要查看Schwartzian变换来缓存计算结果.

如果我们想要通过哈希值进行排序,我们使用哈希键来查找它.我们仍然会得到一个密钥列表,但这次它们按其值排序.

my @keys = sort { $hash{$a} <=> $hash{$b} } keys %hash;
Run Code Online (Sandbox Code Playgroud)

从那里我们可以变得更复杂.如果哈希值相同,我们可以在哈希键上提供二级排序.

my @keys = sort {
$hash{$a} <=> $hash{$b}
or
"\L$a" cmp "\L$b"
} keys %hash;
Run Code Online (Sandbox Code Playgroud)

  • Nit:`lc($ a)cmp lc($ b)`,你也写成"\ L $ a"cmp"\ L $ b"`,并不总能做正确的事情.你想要`fc($ a)cmp fc($ b)`(``\ F $ a"cmp"\ F $ b"`).自5.16起可用. (2认同)