0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[.NET 10] PowerShell で自然順ソート

0
Last updated at Posted at 2026-03-21

はじめに

PowerShell 7.6 が正式公開になりました。

折角なので、.NET10 でサポートされた「数値文字列比較」を利用して PowerShell による自然順ソートの動作確認をしました。

新機能といってもStringComparerクラスに「数値文字列比較」のオプションが追加されただけですので、PowerShell でも簡単に利用できそうです。

(おまけとして、IronPython 3.4.2 による自然順ソートの動作も確認できたので、最後に載せておきます。)

環境

環境は次のとおりです。

PS C:\Users\User> $PSVersionTable.OS
Microsoft Windows 10.0.26200

PS C:\Users\User> [string]$PSVersionTable.PSVersion
7.6.0

PowerShell で自然順ソート

公式ドキュメントの例に倣って LINQでソート(Enumerable.Order)します。

元データとして配列$aを用意しますが、LINQ を使うので[String[]]でキャストしておく必要があります。

最後に既定のソート結果($b)と自然順ソート結果($c)を並べて表示します。

<自然順ソート.ps1>

PowerShell 7.6
$culture = [Globalization.CultureInfo]::CurrentCulture
$options = [Globalization.CompareOptions]::NumericOrdering  # .NET10 で追加
$numericStringComparer = [StringComparer]::Create($culture, $options)

$a = [String[]]@(
  "Log_7_23.txt"
  "Log_7_18.txt"
  "Log_8_4.txt"
  "Log_1_15.txt"
  "Log_6_5.txt"
  "Log_11_28.txt"
  "Log_5_23.txt"
  "Log_5_16.txt"
  "Log_9_8.txt"
  "Log_8_15.txt"
)
$b = [Linq.Enumerable]::Order($a)
$c = [Linq.Enumerable]::Order($a, $numericStringComparer)

[Linq.Enumerable]::Zip($a, $b, $c) |
  Format-Table `
    @{ n = "Original"                     ; e = "Item1" },
    @{ n = "Sorted"                       ; e = "Item2" },
    @{ n = "Sorted with 'NumericOrdering'"; e = "Item3" }

(2026.4.2 冗長なコードを修正)

実行結果

image.png

ここでは期待どおりの結果が得られていますが、実務で利用する場合は十分にテストしてください。

また、Enumerable.Orderを使わずにArray.Sortでも自然順ソートはできます。

Array.Sortは破壊的ソートなので$aのコピーで$b, $cを作成してからソートします。

<自然順ソート.ps1>(Array.Sort版)

PowerShell 7.6
$culture = [Globalization.CultureInfo]::CurrentCulture
$options = [Globalization.CompareOptions]::NumericOrdering  # .NET10 で追加
$numericStringComparer = [StringComparer]::Create($culture, $options)

$a = [String[]]@(
  "Log_7_23.txt"
  "Log_7_18.txt"
  "Log_8_4.txt"
  "Log_1_15.txt"
  "Log_6_5.txt"
  "Log_11_28.txt"
  "Log_5_23.txt"
  "Log_5_16.txt"
  "Log_9_8.txt"
  "Log_8_15.txt"
)
$b = $a.Clone(); [Array]::Sort($b)
$c = $a.Clone(); [Array]::Sort($c, $numericStringComparer)

[Linq.Enumerable]::Zip($a, $b, $c) |
  Format-Table `
    @{ n = "Original"                     ; e = "Item1" },
    @{ n = "Sorted"                       ; e = "Item2" },
    @{ n = "Sorted with 'NumericOrdering'"; e = "Item3" }

(2026.4.2 冗長なコードを修正)

(おまけ)IronPython 3.4.2 で自然順ソート

IronPython の動作環境

.NET10 Runtime が必要です。(2026.4.2 SDK → Runtime に修正)

PS C:\Users\User> dotnet --version
10.0.201

IronPython の起動メッセージから .NET10 上で動作していることが確認できます。
image.png

検証コード

本家 Python の場合は外部ライブラリ(natsort)の利用が近道ですが、 IronPython なら自前で解決できます。

<自然順ソート.py>

IronPython 3.4.2 on .NET10
import System, clr
clr.AddReference("System.Core")
clr.ImportExtensions(System.Linq)

culture = System.Globalization.CultureInfo.CurrentCulture
options = System.Globalization.CompareOptions.NumericOrdering
numericStringComparer = System.StringComparer.Create(culture, options)

a = [
    "Log_7_23.txt",
    "Log_7_18.txt",
    "Log_8_4.txt",
    "Log_1_15.txt",
    "Log_6_5.txt",
    "Log_11_28.txt",
    "Log_5_23.txt",
    "Log_5_16.txt",
    "Log_9_8.txt",
    "Log_8_15.txt",
]
b = a.Order()
c = a.Order(numericStringComparer)  # b, c は .NET のオブジェクト

print("\nOriginal      Sorted        Sorted with 'NumericOrdering'")
print("--------      ------        -----------------------------")
for an, bn, cn in zip(a, b, c):
    print(f"{an:<13} {bn:<13} {cn}")
print()

コード内にコメントしましたがb, cはソート結果を保持する列挙可能な .NET のオブジェクトです。

b, cはリストに変換せず、そのままzip()で処理しています。

実行結果

image.png
問題ありません。

おわりに

PowerShell で簡単に自然順ソートができるのはありがたい。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?