我有一个哈希,键是日期:
my %dates = (
'May 13, 2015' => 8,
'May 7, 2015' => 1,
'Apr 29, 2015' => 2,
'May 12, 2015' => 1,
'Apr 16, 2015' => 13,
'May 6, 2015' => 1,
);
Run Code Online (Sandbox Code Playgroud)
我正试图按日期对它们进行排序.我尝试了两种方法:
foreach my $k (sort {join('', (split ' ', $a)[2,0,1]) <=> join('', (split ' ', $a)[2,0,1])} keys(%dates))
{ print $k . " = " . $dates{$k}; }
Run Code Online (Sandbox Code Playgroud)
由于月份是一个字符串,这不起作用,这:
foreach my $k (sort {join('', (split ' ', $a)[2,0,1]) cmp join('', (split ' ', $a)[2,0,1])} keys(%dates))
{ print $k . " = " . $dates{$k}; }
Run Code Online (Sandbox Code Playgroud)
它也不起作用,它只是把所有4月份放在5月份之前.任何人都知道如何解决它?
您可以使用Time :: Piece解析日期
#!/usr/bin/env perl
use strict;
use warnings;
use Time::Piece;
my %dates = (
'May 13, 2015' => 8,
'May 7, 2015' => 1,
'Apr 29, 2015' => 2,
'May 12, 2015' => 1,
'Apr 16, 2015' => 13,
'May 6, 2015' => 1,
);
for my $k (sort by_date keys %dates) {
print "$k => $dates{$k}\n";
}
sub by_date {
my ($ta, $tb) = map Time::Piece->strptime($_, '%b %d, %Y'), $a, $b;
$ta <=> $tb;
}
Run Code Online (Sandbox Code Playgroud)
输出:
Apr 16, 2015 => 13 Apr 29, 2015 => 2 May 6, 2015 => 1 May 7, 2015 => 1 May 12, 2015 => 1 May 13, 2015 => 8
当然,如果你想放弃Time :: Piece的好处,你可以按照以下几点做一些事情:
#!/usr/bin/env perl
use 5.010;
use strict;
use warnings;
my %dates = (
'May 13, 2015' => 8,
'May 7, 2015' => 1,
'Apr 29, 2015' => 2,
'May 12, 2015' => 1,
'Apr 16, 2015' => 13,
'May 6, 2015' => 1,
);
for my $k (sort by_ugliness keys %dates) {
print "$k => $dates{$k}\n";
}
sub by_ugliness {
state $months = {
do {
my $i = 1;
map {$_ => $i++}
qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec)
}
};
my ($ta, $tb) = map [
/\A (\S+) \s+ ([0-9]{1,2}), \s+ ([0-9]{4})\z/x
], $a, $b;
($ta->[2] <=> $tb->[2]) ||
($months->{ $ta->[0] } <=> $months->{ $tb->[0]}) ||
($ta->[1] <=> $tb->[1]) ;
}
Run Code Online (Sandbox Code Playgroud)
在某些时候,你将开始改进模式匹配.别 ;-)