2014-05-23 5 views
-1

J'ai un tableau des datestri tableau des dates et le retour de l'indice en perl

@dates = qw(2/1/1989 2/1/1970 2/1/1970 2/1/1989 6/1/1970 12/1/1970); 

je dois trier ce du plus ancien au plus récent et retourner l'index du tableau non trié après le tri.

sortie doit quelque chose comme ça

#sorted array 
2/1/1970 
2/1/1970 
6/1/1970 
12/1/1970 
2/1/1989 
2/1/1989 

#indexes 
1 2 4 5 0 3 
+2

Bienvenue sur Stackoverflow. Qu'avez-vous essayé jusqu'à présent? – KeepCalmAndCarryOn

+0

Ces dates sont-elles internationales ou nord-américaines? – Borodin

Répondre

1
my @dates = qw(2/1/1989 2/1/1970 2/1/1970 2/1/1989 6/1/1970 12/1/1970); 

my @idx = map $_->[0], 
    sort { 
    # compare years 
    $a->[3] <=> $b->[3] || 
    # compare months 
    $a->[1] <=> $b->[1] || 
    # compare days 
    $a->[2] <=> $b->[2] || 
    # compare index for stable sort for duplicate values 
    $a->[0] <=> $b->[0] 
    } 
    map [$_, split /\D/, $dates[$_] ], 
    0 .. $#dates; 

print "indexes @idx\n"; 
# sorted values 
print "$_\n" for @dates[@idx]; 

sortie

indexes 1 2 4 5 0 3 
2/1/1970 
2/1/1970 
6/1/1970  
12/1/1970 
2/1/1989 
2/1/1989 
1

En utilisant Time::Piece et un Schwartzian Transform

use strict; 
use warnings; 

use Time::Piece; 

my @dates = qw(2/1/1989 2/1/1970 2/1/1970 2/1/1989 6/1/1970 12/1/1970); 

my @idx = map { $_->[0] } 
    sort { $a->[1] <=> $b->[1] } 
    map { [$_, Time::Piece->strptime($dates[$_], '%m/%d/%Y') ] } 
    (0..$#dates); 

print "Indexes: @idx\n"; 

print "Dates: @dates[@idx]\n"; 

Sorties:

Indexes: 1 2 4 5 0 3 
Dates: 2/1/1970 2/1/1970 6/1/1970 12/1/1970 2/1/1989 2/1/1989 

pourrait aussi le faire comme suit:

my @idx = sort { 
    Time::Piece->strptime($dates[$a], '%m/%d/%Y') <=> Time::Piece->strptime($dates[$b], '%m/%d/%Y') 
} (0..$#dates);