在Perl中排序自定义日期

Den*_*ory 2 perl

我有一个哈希,键是日期:

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月份之前.任何人都知道如何解决它?

Sin*_*nür 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)

在某些时候,你将开始改进模式匹配.别 ;-)