PoshBytes: Why Is My Sort Order So Weird?

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

Leave a Reply

Your email address will not be published. Required fields are marked *