PoshBytes: Why Is My Sort Order So Weird?
Sorting in PowerShell does not always behave the way you expect when numbers are stored as strings. This episode shows how to fix numeric sorting and how to sort by expressions without changing your original data.
This post is a companion for the video embedded below. Scroll down to see the code from the video.
Numeric Values Stored as Strings
This sorts alphabetically, not numerically
$sales = @(
[PSCustomObject]@{Name = 'three-fifty'; Price = '3.50'}
[PSCustomObject]@{Name = 'one'; Price = '1'}
[PSCustomObject]@{Name = 'hundred'; Price = '100'}
[PSCustomObject]@{Name = 'twenty'; Price = '20'}
[PSCustomObject]@{Name = 'ten'; Price = '10'}
[PSCustomObject]@{Name = 'two'; Price = '2'}
)
$sales | Sort-Object Price
Cast to decimal during the sort
$sales | Get-Member
The Fix
Cast to decimal during the sort
$sales | Sort-Object {[decimal]$_.StringInt}
Sorting by an Expression
Sort by class, then by first name
$students = @(
[PSCustomObject]@{Name = 'Toru Hagakure'; Class = '1-A'}
[PSCustomObject]@{Name = 'Katsuki Bakugo'; Class = '1-A'}
[PSCustomObject]@{Name = 'Hiryu Rin'; Class = '1-B'}
[PSCustomObject]@{Name = 'Izuku Midoriya'; Class = '1-A'}
[PSCustomObject]@{Name = 'Kojiro Bondo'; Class = '1-B'}
[PSCustomObject]@{Name = 'Minoru Mineta'; Class = '1-A'}
[PSCustomObject]@{Name = 'Neito Monoma'; Class = '1-B'}
[PSCustomObject]@{Name = 'Reiko Yanagi'; Class = '1-B'}
[PSCustomObject]@{Name = 'Momo Yaoyorozu'; Class = '1-A'}
[PSCustomObject]@{Name = 'Juzo Honenuki'; Class = '1-B'}
)
$students | Sort-Object Class, Name
The Fix
Sort by class, then last name using an expression
$students | Sort-Object Class, {$_.Name.Split(' ')[-1]}
Wrap Up
• Strings sort alphabetically, not numerically
• Cast inside Sort-Object to change comparison type
• Script blocks create calculated sort keys
• Your original objects remain unchanged