Skip to content

Instantly share code, notes, and snippets.

@shiguruikai
Last active April 30, 2021 00:06
Show Gist options
  • Save shiguruikai/2ec9e5583b934e42951f4a6196f886bf to your computer and use it in GitHub Desktop.
Save shiguruikai/2ec9e5583b934e42951f4a6196f886bf to your computer and use it in GitHub Desktop.
function Sort-Naturally {
[CmdletBinding()]
param (
[Parameter(
ValueFromPipeline = $true)]
[object]
$InputObject,
[Parameter(
Position = 0)]
[scriptblock]
$KeySelector = { $_ },
[Parameter()]
[switch]
$Descending
)
begin {
$ErrorActionPreference = 'Stop'
$inputObjects = [System.Collections.Generic.List[object]]::new()
}
process {
if ($null -ne $InputObject) {
foreach ($o in $InputObject) {
if ($null -ne $o) {
$inputObjects.Add($o)
}
}
}
}
end {
try {
$job = Start-Job -ScriptBlock {
Add-Type @'
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace NaturalSort {
public static class NaturalSort
{
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
public static extern int StrCmpLogicalW(string psz1, string psz2);
}
public class NaturalStringComparer : IComparer<object>
{
public int Compare(object x, object y)
{
return NaturalSort.StrCmpLogicalW(x.ToString(), y.ToString());
}
}
}
'@
$list = [System.Collections.Generic.List[object]]::new()
foreach ($o in $Using:inputObjects) {
$list.Add($o)
}
$ks = [scriptblock]::Create("param(`$_) $Using:KeySelector")
if ($Using:Descending) {
return [System.Linq.Enumerable]::OrderByDescending(
$list,
[Func[object, object]] $ks,
[NaturalSort.NaturalStringComparer]::new())
}
else {
return [System.Linq.Enumerable]::OrderBy(
$list,
[Func[object, object]] $ks,
[NaturalSort.NaturalStringComparer]::new())
}
}
Receive-Job -Job $job -Wait
}
finally {
if ($null -ne $job) {
Remove-Job -Job $job -Force
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment