メモ
ソート後の値を返さないものよりも返すほうが、スクリプトの入力面で扱いやすい気がする。
使い捨てスクリプト
# PowerShell 5.1, Windows 11 Set-StrictMode -Version Latest Add-Type -UsingNamespace System.Management.Automation ` -Namespace MyNS -Name MyCls -MemberDefinition @' // String配列 public static string[] SortStr(string[] str) { // 受け取った配列をシャローコピー string[] ret = (string[])str.Clone(); // 並べ替え Array.Sort(ret, (x, y) => StrCmpLogicalW(x, y)); // 配列を返す return ret; } // PSObject配列 public static PSObject[] SortPSObj(PSObject[] obj, string propName = "Name") { // 受け取った配列をシャローコピー PSObject[] ret = (PSObject[])obj.Clone(); // 並べ替え Array.Sort(ret, (x, y) => StrCmpLogicalW( x.Properties[propName].Value.ToString(), y.Properties[propName].Value.ToString() )); // 配列を返す return ret; } // 文字列内の数字をテキストではなく数値と見なして比較 [DllImport( "Shlwapi.dll", CharSet = CharSet.Unicode, EntryPoint = "StrCmpLogicalW" )] private static extern int StrCmpLogicalW( [MarshalAs(UnmanagedType.LPWStr)] string psz1, [MarshalAs(UnmanagedType.LPWStr)] string psz2 ); '@ # フォルダ名 [tmp] $folderPath = "$($env:USERPROFILE)\Desktop\[tmp]" $a1 = @(Get-ChildItem -LiteralPath $folderPath -File) $a2 = @(Get-ChildItem -LiteralPath $folderPath -File) $b = [MyNS.MyCls]::SortStr($a1.Name) $c = [MyNS.MyCls]::SortPSObj($a2) $a1 | Out-String -Width 80 $a2 | Out-String -Width 80 $a1 = $null $a2 = $null $b | Out-String -Width 80 $c | Out-String -Width 80 [MyNS.MyCls]::SortStr(@(9.870, 6.540, 3.210)) | Out-String -Width 80 [MyNS.MyCls]::SortStr(@(-9.87, -6.54, -3.21)) | Out-String -Width 80 [MyNS.MyCls]::SortStr(@("009.87", "06.54", "3.21")) | Out-String -Width 80 $d = @( [PSCustomObject]@{ColA=9.870; ColB=-9.87; ColC="009.87"; Z="a3"} [PSCustomObject]@{ColA=6.540; ColB=-6.54; ColC="06.54"; Z="a01"} [PSCustomObject]@{ColA=3.210; ColB=-3.21; ColC="3.21"; Z="a005"} ) [MyNS.MyCls]::SortPSObj($d, "ColA") | Out-String -Width 80 [MyNS.MyCls]::SortPSObj($d, "ColB") | Out-String -Width 80 [MyNS.MyCls]::SortPSObj($d, "ColC") | Out-String -Width 80 [MyNS.MyCls]::SortPSObj($d, "Z") | Out-String -Width 80