代码之家  ›  专栏  ›  技术社区  ›  Zaid

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

  •  2
  • Zaid  · 技术社区  · 17 年前

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

    use feature 'say';
    
    for my $date (sort {$a cmp $b} keys %data) {
        say $date;
    }
    

    16/07/2008
    16/08/2008
    16/09/2008
    17/07/2008
    17/08/2008
    17/09/2008, etc.
    

    当我需要的是:

    16/07/2008
    17/07/2008
    16/08/2008
    17/08/2008
    16/09/2008
    16/09/2008, etc.
    

    4 回复  |  直到 17 年前
        1
  •  7
  •   larelogio    17 年前

    你可以用 Schwartzian Transform ,就像这样:

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

    %data / 。然后,它按数组的第二个元素排序,并使用另一个元素 map 以获取原始密钥列表。

        2
  •  12
  •   friedo    17 年前

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

    sort { substr($a,3,2) cmp substr($b,3,2) } @dates;
    
        3
  •  7
  •   jrockway    17 年前

    sub get_month {
        my $date = shift;
        my ($d, $m, $y) = split m{/}, $date;
        return $m;
    }
    
    sort { get_month($a) <=> get_month($b) } @dates;
    

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

    my $parser = DateTime::Format::Natural->new(format => 'dd/mm/yyyy');
    sort map { $parser->parse_datetime($_) } @dates;
    
        4
  •  2
  •   brian d foy    17 年前

    perlfaq4 How do I sort an array by (anything)?


    为sort()提供一个比较函数(在perlfunc的sort中描述):

    @list = sort { $a <=> $b } @list;
    

    @idx = ();
    for (@data) {
        ($item) = /\d+\s*(\S+)/;
        push @idx, uc($item);
        }
    @sorted = @data[ sort { $idx[$a] cmp $idx[$b] } 0 .. $#idx ];
    

    也可以这样写,使用一种被称为Schwartzian变换的技巧:

    @sorted = map  { $_->[0] }
        sort { $a->[1] cmp $b->[1] }
        map  { [ $_, uc( (/\d+\s*(\S+)/)[0]) ] } @data;
    

    如果您需要对多个字段进行排序,以下范例很有用。

    @sorted = sort {
        field1($a) <=> field1($b) ||
        field2($a) cmp field2($b) ||
        field3($a) cmp field3($b)
        } @data;
    

    这可以方便地与如上所述的密钥预计算相结合。

    http://www.cpan.org/misc/olddoc/FMTEYEWTK.tgz 了解有关此方法的更多信息。