2010-03-22 14 views
7

Come posso ordinare le date in Perl?Come posso ordinare le date in Perl?

my @dates = ("02/11/2009" , "20/12/2001" , "21/11/2010"); 

Ho sopra le date nel mio array. Come posso ordinare quelle date?

Il mio formato data è dd/mm/YYYY.

+11

La memorizzazione delle date come "AAAA/MM/GG" è molto più semplice. Puoi fare quello che vuoi quando li mostri. –

risposta

18
@dates = sort { join('', (split '/', $a)[2,1,0]) cmp join('', (split '/', $b)[2,1,0]) } @dates; 

o utilizzando subroutine di ordinamento separato:

sub mysort { 
    join('', (split '/', $a)[2,1,0]) cmp join('', (split '/', $b)[2,1,0]); 
} 
@dates = sort mysort @dates; 

Update: Un approccio più efficace è la Trasformata di Schwartz:

@dates = 
    map $_->[0], 
    sort { $a->[1] cmp $b->[1] } 
    map [ $_, join('', (split '/', $_)[2,1,0]) ], @dates; 
+4

Fate questo con una trasformazione di Schwartzian o un altro tipo di chiave memorizzata nella cache in modo da non dover ricalcolare i valori ogni volta. –

+0

@brian: Grazie, ho dimenticato questo :-) –

3

preferisco il formato YYYY/MM/DD meglio, proprio per questo motivo. È garantito per ordinare correttamente le date, tra 1000/01/01 e 9999/12/31.

my @sorted_alt = sort map { join '/', reverse split '/', $_ } @dates; 

Se si ha realmente bisogno in formato DD/MM/YYYY, si può sempre andare per una completa Schwartzian transform.

my @sorted = map { 
    join '/', reverse split '/', $_ 
} 
sort 
map { 
    join '/', reverse split '/', $_ 
} @dates; 

o

my @sorted = map { 
    join '/', reverse @$_ 
} 
sort { "@$a" cmp "@$b" } 
map { 
    [ reverse split '/', $_ ] 
} @dates; 
1

Oppure utilizzare il formato epoca in timestamp e ordinarli come numeri. Quindi converti le stringhe di data in output come desideri. Quindi non sei bloccato con la formattazione delle stringhe di origine.

+2

Sarebbe utile se hai mostrato come fare questo. Puoi aggiungere un esempio? – slm

1

Molte persone hanno argomentato correttamente che il formato originale delle date dovrebbe essere nel formato aaaa-mm-gg, ma nessuno ha dato il codice Perl che può ancora gestire il caso. Ecco quindi:

my @dates = (
    '2014-08-15', 
    '2016-09-13', 
    '2001-01-02', 
    '1998-09-22', 
    '1998-09-21', 
    '1998-09-23', 
    '1999-04-20', 
    '2020-01-30', 
); 

@dates = sort {$a cmp $b} @dates; # 1998 is the first date's year 
@dates = sort {$b cmp $a} @dates; # 2014 is the first date's year 
+0

La risposta di Brad Gilbert contiene il codice per quel caso. È solo '@dates = sort @ date;'. – melpomene

+0

Ah, buon punto - ma mi piace il mio esempio perché in realtà funziona su una serie di valori corretti (nessuna magia della mappa divisa), mostra entrambi gli ordini nello spiegare l'ascendente rispetto alla discesa e non interpola inutilmente i valori ordinati. – HoldOffHunger

Problemi correlati