2010-03-22 87 views
7

如何在Perl中對日期進行排序?如何在Perl中對日期進行排序?

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

我在數組中有上述日期。我怎樣才能排序這些日期?

我的日期格式是dd/mm/YYYY

+11

以'YYYY/MM/DD'存儲日期變得更容易。當你展示他們時你可以做任何你想做的事情。 – 2010-03-22 11:14:03

回答

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

,或者使用不同的排序子程序:

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

更新:更有效的方法是使用Schwartzian變換:

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

使用Schwartzian Transform或其他緩存鍵排序來執行此操作,因此您不必每次重新計算值。 – 2010-03-22 15:32:51

+0

@brian:謝謝,我忘記了這一點:-) – 2010-03-22 16:10:59

3

我喜歡YYYY/MM/DD格式更好,因爲這個原因。確保在1000/01/019999/12/31之間正確排序。

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

如果你真的需要它DD/MM/YYYY格式,你總是可以去一個完整Schwartzian transform

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

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

或者使用紀元格式的時間戳,並將它們分類爲數字。然後根據需要轉換日期字符串輸出。然後你不會被格式化原始字符串。

+2

如果你展示瞭如何做到這一點,將會有所幫助。你可以添加一個例子嗎? – slm 2013-02-04 14:36:05

1

很多人在這裏爭辯說日期的原始格式應該是yyyy-mm-dd格式,但是沒有人給出可以處理這種情況的Perl代碼。所以這裏是:

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

布拉德吉爾伯特的答案包含這種情況下的代碼。它只是'@dates = sort @dates;'。 – melpomene 2016-10-08 15:16:02

+0

啊,好點 - 但我喜歡我的例子,因爲它實際上工作在一個正確值的數組上(沒有拆分映射魔術),它在解釋升序和降序時都顯示了這兩個順序,並且它不會不必要地插值排序的值。 – HoldOffHunger 2016-10-08 16:58:25

相關問題