如何使用Perl按月对dd/mm/yyyy格式化日期进行排序?

Zai*_*aid 2 sorting perl date

我有一个存储在哈希中的dd/mm/yyyy日期列表,我需要按月按顺序依次打印出来.这是相关的摘录.

use feature 'say';

for my $date (sort {$a cmp $b} keys %data) {
    say $date;
}
Run Code Online (Sandbox Code Playgroud)

这输出:

16/07/2008
16/08/2008
16/09/2008
17/07/2008
17/08/2008
17/09/2008, etc.
Run Code Online (Sandbox Code Playgroud)

当我需要的是:

16/07/2008
17/07/2008
16/08/2008
17/08/2008
16/09/2008
16/09/2008, etc.
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点?

fri*_*edo 12

您可以使用Schwartzian变换来完成,如下所示:

for my $date( map  { $_->[0] }
              sort { $a->[1] <=> $b->[1] } 
              map  { [ $_, (split /\//, $_)[1] ] }
              keys %data ) { 
    ...
Run Code Online (Sandbox Code Playgroud)

这将获取每个键%data并将其放入一个匿名数组中,其中第一个元素是键,第二个元素是分裂的中间字段/.然后它按数组的第二个元素排序,并使用另一个元素map获取原始的键列表.


lar*_*gio 7

如果格式是一个严格的10个字符:

sort { substr($a,3,2) cmp substr($b,3,2) } @dates;
Run Code Online (Sandbox Code Playgroud)

  • 过早优化是万恶之源.难道你不认为"substr"会比哈希查找更快或更快吗? (3认同)

jro*_*way 6

解析和排序:

sub get_month {
    my $date = shift;
    my ($d, $m, $y) = split m{/}, $date;
    return $m;
}

sort { get_month($a) <=> get_month($b) } @dates;
Run Code Online (Sandbox Code Playgroud)

我可能会使用DateTime,因为我想处理对象,而不是无意义的字符串:

my $parser = DateTime::Format::Natural->new(format => 'dd/mm/yyyy');
sort map { $parser->parse_datetime($_) } @dates;
Run Code Online (Sandbox Code Playgroud)