在Perl中,如何使用自定义排序对哈希键进行排序?

时间:2011-11-17 17:24:45

标签: perl sorting hash foreach

我正在尝试对文件散列进行操作,并且必须按特定顺序完成工作。大多数人会说列表可以这样订购:

for my $k (sort keys %my_hash)
{
    print "$k=>$my_hash{$k}, ";
}

但是,我需要非字母顺序,实际上密钥以_开头,然后GdigitsL到任意{{1} (例如。M,P,R,T or Dword_G.txt,...,word_2.txt)。有没有办法按自定义顺序排序?

3 个答案:

答案 0 :(得分:12)

  

有没有办法按自定义顺序排序?

是。请参阅sort

例如:

#!/usr/bin/env perl

use warnings; use strict;

my @order = qw(G 1 2 3 L M P R T D);

my %order_map = map { $order[$_] => $_ } 0 .. $#order;

my $pat = join '|', @order;

my @input = qw(word_P.txt word_2.txt word_G.txt);

my @sorted = sort {
    my ($x, $y) = map /^word_($pat)[.]txt\z/, $a, $b;
    $order_map{$x} <=> $order_map{$y}
} @input;

print "@sorted\n";

答案 1 :(得分:4)

use 5.014;

sub rank {
    my ($word) = @_;
    $word =~ s{\A \w+ _}{}msx;
    return do {
        given ($word) {
            0 when /\A G/msx;
            1 when /\A [0-9]/msx;
            2 when /\A L/msx;
            3 when /\A [MPRTD]/msx;
            default { 1000 };
        }
    };
}

say for sort { rank($a) <=> rank($b) } qw(word_P.txt word_2.txt word_G.txt);

输出:

word_G.txt
word_2.txt
word_P.txt

编辑:在Perl 5.14之前,使用临时变量。

use 5.010;
⋮
return do {
    my $dummy;
    given ($word) {
        $dummy = 0 when /\A G/msx;
        $dummy = 1 when /\A [0-9]/msx;
        $dummy = 2 when /\A L/msx;
        $dummy = 3 when /\A [MPRTD]/msx;
        default { $dummy = 1000 };
    }
    $dummy;
};

答案 2 :(得分:0)

我有一个特定的用例,我想先用某些值排序,其他值最后排序,然后在中间按字母顺序排序。

这是我的解决方案:

my @sorted = sort {
    my @order = qw(Mike Dave - Tom Joe);
    my ($x,$y) = (undef,undef);
    for (my $i = 0; $i <= $#order; $i++) {
        my $token = $order[$i];
        $x = $i if ($token eq $a or (not defined $x and $token eq "-"));
        $y = $i if ($token eq $b or (not defined $y and $token eq "-"));
    }
    $x <=> $y or
    $a cmp $b
} @ARGV;

输出:

$ perl customsort.pl Tom Z Mike A Joe X Dave G
Mike Dave A G X Z Tom Joe