🏹

PowerShellで独自順番でソートする

2024/06/10に公開

サマリー

独自の順番でソートしたいことありませんか?

String.IndexOf でできますよ、というお話。

Sort-Object

Sort-Object で @{Expression={なんたら}} としていろいろできるのは非常に便利なわけですが、特定の順番にしたいときには一筋縄ではいかないことが多いかと思います。

一番簡単なのはソートするデータに並べ替え用のキーをつけることですが、それはそれで面倒なことも。やりたいことは単にソートだけ、という場合はなおさらに。

例えばこんな場合ですね。地名を北から順に、とか。Excelできるのか……。

http://officetanaka.net/excel/vba/tips/tips189.htm

Stack Overflow での回答

と探していたら Stack Overflow で同じことを質問している人を発見しました。

https://stackoverflow.com/questions/48701384/powershell-custom-order-sorting

なるほど。String.IndexOf を使えと。未知のキーが来ると最初になるから要注意と。

降順でやるのがいいのでは

未知のキーをどうするかですが、最初に来てほしくない、あるいは主要なキーだけ順序を指定してあとはなおざりで、という場合には降順でやればいいのでは。

$customOrder = "3番目に来てほしいキー","2番目に来てほしいキー","最初に来てほしいキー"

などとしておいて

$data |Sort-Object @{Expression={$customOrder.IndexOf(キー);Descending=1}

でOK。

やってみる

Stack Overflow での例で実際にやってみると、

C:\> $customOrder = "Success","Warning","Failed"
C:\> $testdata = @()
C:\> $testdata += ,@{Server="server1";Result="Success"}
C:\> $testdata += ,@{Server="server2";Result="Success"}
C:\> $testdata += ,@{Server="server3";Result="Warning"}
C:\> $testdata += ,@{Server="server4";Result="Success"}
C:\> $testdata += ,@{Server="server7";Result="Failed"}
C:\> $testdata|Sort @{Expression={$customOrder.IndexOf($_.Result)};Descending=1} |%{"$($_.Server),$($_.Result)"}

server7,Failed
server3,Warning
server1,Success
server2,Success
server4,Success

未知のデータも入れてみる。

C:\> $testdata += ,@{Server="serverX";Result="Running"}
C:\> $testdata|Sort @{Expression={$customOrder.IndexOf($_.Result)};Descending=1} |%{"$($_.Server),$($_.Result)"}

server7,Failed
server3,Warning
server1,Success
server2,Success
server4,Success
serverX,Running

元アイディアを出した Tomalak に感謝!!

Discussion