2010-03-22 9 views
7

¿Cómo puedo ordenar las fechas en Perl?¿Cómo puedo ordenar las fechas en Perl?

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

Tengo más fechas en mi matriz. ¿Cómo puedo ordenar esas fechas?

Mi formato de fecha es dd/mm/YYYY.

+11

El almacenamiento de fechas como 'YYYY/MM/DD' es mucho más fácil. Puede hacer lo que quiera cuando los muestre. –

Respuesta

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

o el uso de subrutina de clasificación por separado:

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

Actualización: Un enfoque más eficiente es el Schwartzian Transform:

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

Haga esto con una Transformación de Schwartz u otra ordenación de clave almacenada en caché para que no tenga que recalcular los valores cada vez. –

+0

@brian: Gracias, me olvidé de esto :-) –

3

prefiero el formato YYYY/MM/DD mejor, precisamente por esta razón. Está garantizado para ordenar las fechas correctamente, entre 1000/01/01 y 9999/12/31.

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

Si realmente lo necesita en DD/MM/YYYY formato, siempre se puede ir a 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

O utilice el formato época en la marca de tiempo y clasificarlos como números. A continuación, convierta las cadenas de fechas a la salida que desee. Entonces no está atascado con el formato de las cadenas de origen.

+2

Sería útil si mostrara cómo hacerlo. ¿Puedes agregar un ejemplo? – slm

1

Mucha gente aquí argumentó correctamente que el formato original de las fechas debe ser en formato aaaa-mm-dd, pero nadie ha dado el código Perl que puede manejar ese caso todavía. Así que aquí está:

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 respuesta de Brad Gilbert contiene el código para ese caso. Es simplemente '@dates = sort @dates;'. – melpomene

+0

Ah, buen punto, pero me gusta mi ejemplo porque realmente funciona en una matriz de valores correctos (sin magia de mapa dividido), muestra ambas órdenes explicando ascendente o descendente, y no interpola innecesariamente los valores ordenados. – HoldOffHunger

Cuestiones relacionadas