在Perl中对字母数字散列键排序?

在Perl中对字母数字散列键排序?,perl,sorting,Perl,Sorting,给定以下哈希: %错误=( “2013-W9->2013-W12”=>1, “2013-W5->2013-W8”=>1, “2013-W13->2013-W15”=>1 ) 我正试图这样对它进行排序(这样我就可以在foreach循环中使用它): %错误=( “2013-W5->2013-W8”=>1, “2013-W9->2013-W12”=>1, “2013-W13->2013-W15”=>1 ) 我尝试了sort keys%errors和sort{$a$b)keys%errors但没有成

给定以下哈希:

%错误=(
“2013-W9->2013-W12”=>1,
“2013-W5->2013-W8”=>1,
“2013-W13->2013-W15”=>1
)
我正试图这样对它进行排序(这样我就可以在
foreach
循环中使用它):

%错误=(
“2013-W5->2013-W8”=>1,
“2013-W9->2013-W12”=>1,
“2013-W13->2013-W15”=>1
)
我尝试了
sort keys%errors
sort{$a$b)keys%errors
但没有成功


如何解决此问题?

将按升序为
yyyy Wx
对键进行排序;首先比较
yyy
,然后比较
x
数字

my @sorted_keys = map $_->[0],
  sort {
    $a->[1] <=> $b->[1]
    ||
    $a->[2] <=> $b->[2]
  }
  map [ $_, /(\d+)/g ],
  keys %errors;
my@sorted\u keys=map$\u->[0],
分类{
$a->[1]$b->[1]
||
$a->[2]$b->[2]
}
地图[$\ux,/(\d+)/g],
键%错误;

不完全清楚您想要什么样的排序顺序,但这种方法可以很容易地扩展:

#!/usr/bin/perl

use strict;
use warnings;
use 5.010;

my %errors = (
    "2013-W9 -> 2013-W12" => 1,
    "2013-W5 -> 2013-W8" => 1,
    "2013-W13 -> 2013-W15" => 1
);

my @sorted_keys = map { $_->[0] }
  sort { $a->[1] <=> $b->[1] }
  map  { [ $_, /W(\d+)/ ] } keys %errors;

say $_ for @sorted_keys;
!/usr/bin/perl
严格使用;
使用警告;
使用5.010;
我的%errors=(
“2013-W9->2013-W12”=>1,
“2013-W5->2013-W8”=>1,
“2013-W13->2013-W15”=>1
);
我的@sorted_keys=map{$\u->[0]}
排序{$a->[1]$b->[1]}
映射{[$\u,/W(\d+/])键%errors;
对@sorted_键使用$_;

在这里,有一个通用的字符串排序例程,它将数字子字符串作为数字进行比较,用包括Perl在内的多种语言实现。

在这种情况下,CPAN模块
排序::自然地
工作正常:

use Sort::Naturally qw(nsort);
say $_ for nsort keys %errors;

我也遇到过类似的情况。我通过以下方式解决了我的问题:

你试过了吗

sort keys %errors


你会在这些键中看到其他字母吗?例如
2013-X12
?当你调用排序键时,它是如何排序哈希的%错误?是的,我可能也会看到其他字母,比如M代表月份。W代表周。顺便说一句,也许我需要更多的咖啡……这不是正确的吗?9比13小。但另一方面,它可能会随后出现问题t编号,如hmm…
2013-1->2013-99
vs
2013-10->2013-1
我想正确的方法是在这种情况下用零填充数字,这样
9
->
09
。然后你必须知道最大长度有多长,并且你必须确保不超过最大整数大小(对于非常长的字符串),也许您最初的方法毕竟是更简单的选择。
sort{$a <=> $b) keys %errors
my %errors = (
    "2013-W9 -> 2013-W12" => 1,
    "2013-W5 -> 2013-W8" => 1,
    "2013-W13 -> 2013-W15" => 1);

foreach my $val(sort {my ($anum) = ($a =~ /\d+-\w(\d+)$/);  my ($bnum) = ($b =~ /\d+-\w(\d+)$/);  $anum <=> $bnum} keys %error
{
    print "$val\n";
}
2013-W5 -> 2013-W8
2013-W9 -> 2013-W12
2013-W13 -> 2013-W15