Perl sort:如何对输出进行排序

时间:2014-07-29 05:16:28

标签: perl sorting hash

如何对这样的输出进行排序

电流:

Shift : 01 
TOTAL # OF OT ENTRIES ====> 15937 
# OF UN-ACCOUNTED GAPS ====> 455 
GAP MINUTUES ====> 22158 
# OF OFFICERS ====> 28 
TOTAL # OF OT TICKETS WRITTEN ====> 1708 
TICKET WRITTEN ====> 19929 

我想这样排序: (信息:我初始化了这样的哈希值,但它没有按顺序打印)

Shift : 01 
# OF OFFICERS ====> 28 
# OF UN-ACCOUNTED GAPS ====> 455 
TOTAL # OF OT ENTRIES ====> 15937
TOTAL # OF OT TICKETS WRITTEN ====> 1708 
TICKET WRITTEN ====> 19929 
GAP MINUTUES ====> 22158 

我的代码:

foreach my $k (sort keys %Shift_name) {
    print "\n\n$k \n";
    while (my ($kk, $val) = each %{ $Shift_name{$k} }) {
        print  " $kk ====> $val \n";
    }
}

2 个答案:

答案 0 :(得分:2)

您的密钥顺序显示为任意。

因此,您必须创建一个单独的散列,指定排序使用的键的顺序。

以下内容证明了这一点:

use strict;
use warnings;

# Load Data into hash
my %data = split /\s*====>\s*|\n/, do {local $/; <DATA>};

# Specify order of keys
my @order = (
    '# OF OFFICERS', 
    '# OF UN-ACCOUNTED GAPS', 
    'TOTAL # OF OT ENTRIES',
    'TOTAL # OF OT TICKETS WRITTEN', 
    'TICKET WRITTEN',
    'GAP MINUTUES',
); 
my %order = do {my $i = 0; map {$_ => ++$i} @order};

for my $key (sort {$order{$a} <=> $order{$b}} keys %data) {
    print "$key ====> $data{$key}\n";
}

__DATA__
TOTAL # OF OT ENTRIES ====> 15937 
# OF UN-ACCOUNTED GAPS ====> 455 
GAP MINUTUES ====> 22158 
# OF OFFICERS ====> 28 
TOTAL # OF OT TICKETS WRITTEN ====> 1708 
TICKET WRITTEN ====> 19929

输出:

# OF OFFICERS ====> 28 
# OF UN-ACCOUNTED GAPS ====> 455 
TOTAL # OF OT ENTRIES ====> 15937 
TOTAL # OF OT TICKETS WRITTEN ====> 1708 
TICKET WRITTEN ====> 19929
GAP MINUTUES ====> 22158 

答案 1 :(得分:-1)

List::Util pair函数在使用哈希时非常理想(从5.20开始它们就在核心中!)。如果您的数据结构如下所示:

my %shift_name = (
    28    => '# OF OFFICERS',
    455   => '# OF UN-ACCOUNTED GAPS',
    1708  => 'TOTAL # OF OT TICKETS WRITTEN',
    15937 => 'TOTAL # OF OT ENTRIES',
    19929 => 'TICKET WRITTEN',
    22158 => 'GAP MINUTES',
);

您可以按照以下键键打印出来:

use List::Util qw(pairmap);
print join "\n", 
    map     { "$_->[1] ====> $_->[0]" }
    sort    { $a->[0] <=> $b->[0] } 
    pairmap { [$a, $b] } %shift_name;

类似于Schwartzian变换,但在这种情况下,匿名数组仅用于将键/值对保持在一起。如果哈希被反转

my %shift_name = (
    '# OF OFFICERS'          => 28,
    '# OF UN-ACCOUNTED GAPS' => 455,
    ...

同样的一般想法适用,但你必须调整指数:

print join "\n", 
    map     { "$_->[0] ====> $_->[1]" }
    sort    { $a->[1] <=> $b->[1] } 
    pairmap { [$a, $b] } %shift_name;

两个输出

# OF OFFICERS ====> 28
# OF UN-ACCOUNTED GAPS ====> 455
TOTAL # OF OT TICKETS WRITTEN ====> 1708
TOTAL # OF OT ENTRIES ====> 15937
TICKET WRITTEN ====> 19929
GAP MINUTES ====> 22158

(我假设在您的预期输出中,1708条目是在15937条目之后是一个错字。如果您确实需要任意订单,请忽略此答案并参见米勒。)