Как указал @Lee_Dailey, самым простым решением было бы приведение строк к типу System.Version
:
PS /home/me> <b>$s1 = '1.2.3'</b>
PS /home/me> <b>$s2 = '1.19.2'</b>
PS /home/me> <b>[Version]$v1 = $s1</b>
PS /home/me> <b>[Version]$v2 = $s2</b>
PS /home/me> <b>$v1</b>
Major Minor Build Revision
----- ----- ----- --------
1 2 3 -1
PS /home/me> <b>$v2</b>
Major Minor Build Revision
----- ----- ----- --------
1 19 2 -1
PS /home/me> <b>$v1 -gt $v2</b>
False
PS /home/me> <b>$v2 -gt $v1</b>
True
Я только что протестировал это в PowerShell Core 6.1 в Linux, и он работал просто отлично, поэтомуЯ ожидаю, что он будет работать и в PowerShell Core на Mac OS X.
Однако вы также можете использовать тот же подход, который вы используете в Python: создавать кортежи изstrings.
PS /home/me> <b>$s1 = '1.2.3'</b>
PS /home/me> <b>$s2 = '1.19.2'</b>
PS /home/me> <b>[int[]]$v1 = $s1.Split('.')</b>
PS /home/me> <b>[int[]]$v2 = $s2.Split('.')</b>
PS /home/me> <b>$t1 = New-Object 'Tuple[int,int,int]' $a1</b>
PS /home/me> <b>$t2 = New-Object 'Tuple[int,int,int]' $a2</b>
PS /home/me> <b>$t1</b>
Item1 Item2 Item3 Length
----- ----- ----- ------
1 2 3 3
PS /home/me> <b>$t2</b>
Item1 Item2 Item3 Length
----- ----- ----- ------
1 19 2 3
PS /home/me> <b>$t1 -gt $t2</b>
False
PS /home/me> <b>$t2 -gt $t1</b>
True
Обратите внимание, что разбиение строки даст вам строковый массив, поэтому вы ДОЛЖНЫ привести его к целочисленному массиву, иначе сравнения не будут работать правильно (так как сравнения строк, а не числовые сравненияиспользоваться).
Обратите также внимание, что количество элементов в определении типа (Tuple[<type>,<type>,...]
) ДОЛЖНО совпадать с количеством элементов в массиве, из которого создается кортеж. Этот ответ показывает многократно используемую функцию для создания кортежей из произвольных массивов:
function New-Tuple {
Param(
[Parameter(
Mandatory=$true,
ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true
)]
[ValidateCount(2,20)]
[array]$Values
)
Process {
$types = ($Values | ForEach-Object { $_.GetType().Name }) -join ','
New-Object "Tuple[$types]" $Values
}
}
, чтобы вы могли изменить
$t1 = New-Object 'Tuple[int,int,int]' $a1
$t2 = New-Object 'Tuple[int,int,int]' $a2
на
$t1 = New-Tuple $a1
$t2 = New-Tuple $a2
Остерегайтесь, однако, что сравнение кортежей требует, чтобы они имели одинаковое количество элементов, иначе сравнение не удастся:
PS /home/me> <b>$s3 = '1.19.2.1'</b>
PS /home/me> <b>[int[]]$a3 = $s3.Split('.')</b>
PS /home/me> <b>$t3 = New-Object 'Tuple[int,int,int,int]' $a3</b>
PS /home/me> <b>$t3 -gt $t2</b>
<i>Could not compare "(1, 19, 2, 1)" to "(1, 19, 2)". Error: "Cannot convert the
"(1, 19, 2)" value of type "<b>System.Tuple`3</b>[[System.Int32, System.Private.CoreLib,
Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Int32,
System.Private.CoreLib, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=7cec85d7bea7798e],[System.Int32, System.Private.CoreLib,
Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]" to type
"<b>System.Tuple`4</b>[System.Int32,System.Int32,System.Int32,System.Int32]"."</i>
At line:1 char:1
+ $t3 -gt $t2
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : ComparisonFailure
Поэтому вы должны убедиться, что кортежи версий всегда имеют одинаковую длину, например, добавляя0
элементов в массив, а затем выбирают первые 4 элемента из результата:
[int[]]$a = ('1.2'.Split('.') + (0, 0, 0, 0))[0..3]
$t = New-Object 'Tuple[int,int,int,int]' $a
У ускорителя типа [Version]
такой проблемы нет, поскольку он создает объекты того же типа, где отсутствуетчисла в строке версии автоматически заполняются значением -1
.
PS /home/me> <b>[Version]'1.2'</b>
Major Minor Build Revision
----- ----- ----- --------
1 2 -1 -1
PS /home/me> <b>[Version]'1.2.3'</b>
Major Minor Build Revision
----- ----- ----- --------
1 2 3 -1
PS /home/me> <b>[Version]'1.2.3.4'</b>
Major Minor Build Revision
----- ----- ----- --------
1 2 3 4