如何通过多个键对perl哈希进行排序?

时间:2016-01-16 21:54:05

标签: perl sorting hash

您好我有一个以下形式的数据结构:

$data = {                                                                                           
    'a' => { key1 => 2, key2 => 1 },                                                                   
    'b' => { key1 => 1, key2 => 2 },                                                                   
    'c' => { key1 => 1, key2 => 1 },                                                                   
    'd' => { key1 => 3, key2 => 2 },                                                                   
    'e' => { key1 => 3, key2 => 1 },                                                                   
    'f' => { key1 => 1, key2 => 2 },                                                                   
};

我希望能够做的是按key2的升序,key1的降序,然后是散列键的升序循环遍历此数据结构,例如:

e
a
c
d
b
f

我怎样才能在perl中实现这一目标?我知道我可以使用sort keys %$data按键对哈希进行排序,但是如何按多个值和键排序呢?

1 个答案:

答案 0 :(得分:9)

之前已经提出了类似的问题,可在此处找到: Sorting an Array of Hash by multiple keys Perl

基本上,Perl有两个用于排序的运算符,<=>cmp返回-1,0或1,具体取决于左侧是否小于,等于或大于右侧。 <=>用于数字比较,cmp用于字符串比较。有关其使用的更多详细信息,请访问:Equality Operators

这些运算符可以与Perl的sort函数一起使用,并与or运算符结合使用,可以用来实现您之后的结果:

#!/usr/bin/perl

use strict;
use warnings;

my $data = {
    'a' => { key1 => 2, key2 => 1 },
    'b' => { key1 => 1, key2 => 2 },
    'c' => { key1 => 1, key2 => 1 },
    'd' => { key1 => 3, key2 => 2 },
    'e' => { key1 => 3, key2 => 1 },
    'f' => { key1 => 1, key2 => 2 },
};

my @sorted = sort {
        $data->{$a}->{key2} <=> $data->{$b}->{key2} or
        $data->{$b}->{key1} <=> $data->{$a}->{key1} or
        $a cmp $b
    } keys %{$data};

for my $key (@sorted){
    print "$key\n";
}

由于<=>cmp返回0(false)表示相等,这意味着我们可以将同等检查与or||链接在一起。

在上面的示例中,我们$a$b在特定的排序迭代中引用$data hashref的键。使用这些密钥,我们可以访问散列的特定值,例如$data->{$a}->{key2}。通过将$a放在$b之前,它会导致排序按升序排列,而$b放在$a之前将导致排序按降序排列。