快速对包含大量日期的数组进行排序

Sort an array containing a lot of dates quickly

我有一个包含日期的巨大数组。日期具有以下形式:tt.mm.yyyy。我知道如何用 Sort-Object 对数组进行排序,但是排序需要很多时间。我找到了另一种排序数组的方法,但它没有按预期工作。

我以前对数组进行排序的代码是这样的。

$data | Sort-Object { [System.DateTime]::ParseExact($_, "dd.MM.yyyy", $null) }

但正如我之前所说:这种排序方式太慢了。 System.Array 中的 Sort() 方法似乎要快得多。

[Array]::Sort([array]$array)

此代码对包含字符串的数组进行排序比 Sort-Object 快得多。有什么方法可以像 Sort-Object 方法一样更改上述排序方法?

如果您确保数组的类型为 DateTime,则 .NET 方法将适用于日期。

意味着你应该使用

[DateTime[]]$dateArray

而不是

[Array]$dateArray

创建时。然后你可以使用

[Array]::Sort($dateArray)

自行排序...

您的输入数据是日期格式的日期字符串,不允许按 "date" 顺序排序。您必须将字符串转换为实际日期

Get-Date $_
[DateTime]::ParseExact($_, "dd.MM.yyyy", $null)

或将字符串日期的格式更改为 ISO 格式,这样可以按日期顺序排序。

'{2}-{1}-{0}' -f ($_ -split '.')
'{0}-{1}-{2}' -f $_.Substring(6,4), $_.Substring(3,2), $_.Substring(0,2)
$_ -replace '(\d+)\.(\d+).(\d+)', '--'

在某些时候,您必须执行其中一种转换,无论是在创建数据时还是在排序时。

我运行一些测试每次转换的WRT性能,使用Substring()方法的字符串t运行sformation似乎是最快的方法:

PS C:\> <b>$dates = 1..10000 | %{</b>
>> <b>$day = Get-Random -Min 1 -Max 28</b>
>> <b>$month = (Get-Random -Min 1 -Max 12</b>
>> <b>$year = Get-Random -Min 1900 -Max 2014</b>
>> <b>'{0:d2}.{1:d2}.{2}' -f $day, $month, $year</b>
>> <b>}</b>
>>
PS C:\> <b> 测量命令 { $dates |排序 {Get-Date $_} }</b>

天 : 0
小时 : 0
分钟 : 0
秒数:1
毫秒:520
滴答声:15200396
总天数:1,75930509259259E-05
总小时数:0,000422233222222222
总分钟数:0,0253339933333333
总秒数:1,5200396
总毫秒数:1520,0396

PS C:\> <b> 测量命令 { $dates |排序 {'{2}-{1}-{0}' -f ($_ -split '.')} }</b>

天 : 0
小时 : 0
分钟 : 0
秒数:0
毫秒:413
滴答声:4139027
总天数:4,79054050925926E-06
总小时数:0,000114972972222222
总分钟数:0,00689837833333333
总秒数:0,4139027
总毫秒数:413,9027

PS C:\> <b> 测量命令 { $dates |排序 {$_ -replace '(\d+)\.(\d+).(\d+)', '$3-$2-$1'} }</b>

天 : 0
小时 : 0
分钟 : 0
秒数:0
毫秒:348
滴答声:3488962
总天数:4,03815046296296E-06
总小时数:9,69156111111111E-05
总分钟数:0,00581493666666667
总秒数:0,3488962
总毫秒数:348,8962

PS C:\> <b> 测量命令 { $dates |排序 {[DateTime]::ParseExact($_, "dd.MM.yyyy", $null)} }</b>

天 : 0
小时 : 0
分钟 : 0
秒数:0
毫秒:340
滴答声:3408966
总天数:3,9455625E-06
总小时数:9,46935E-05
总分钟数:0,00568161
总秒数:0,3408966
总毫秒数:340,8966

PS C:\> <b> 测量命令 { $dates |排序 {'{0}-{1}-{2}' -f $_.Substring(6,4), $_.Substring(3,2), $_.Substring(0, 2)} }</b>

天 : 0
小时 : 0
分钟 : 0
秒数:0
毫秒:292
滴答声:2926835
总天数:3,38754050925926E-06
总小时数:8,13009722222222E-05
总分钟数:0,00487805833333333
总秒数:0,2926835
总毫秒数:292,6835