我正在尝试对文件散列进行操作,并且必须按特定顺序完成工作。大多数人会说列表可以这样订购:
for my $k (sort keys %my_hash)
{
print "$k=>$my_hash{$k}, ";
}
但是,我需要非字母顺序,实际上密钥以_
开头,然后G
到digits
到L
到任意{{1} (例如。M,P,R,T or D
,word_G.txt
,...,word_2.txt
)。有没有办法按自定义顺序排序?
答案 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