Using Sort-Object on array of hash tables
Sort-Object a
is not working because a
isn't a property, it's a key in a hashtable. One might be confused because PowerShell hides this for you by accepting $ht.a
even though it actually uses $ht["a"]
behind the scenes, but if you run $array | Get-Member
you can confirm that the property a
doesn't exist.
A workaround is to sort by using calculated properties that access the keys in the hashtable. I used Select-Object
to show the hashtables in a table so it's easier to see the results. Ex:
$array = @()$array += @{a = 7; b = 2}$array += @{a = 3; b = 4}$array += @{a = 3; b = 1}$array += @{a = 5; b = 9}$array += @{a = 1; b = 5}#No sort$array | Select-Object @{n="a";e={$_.a}}, @{n="b";e={$_.b}}a b- -7 23 43 15 91 5#Sort by a asc, then b asc$array | Sort-Object { $_.a }, { $_.b } | Select-Object @{n="a";e={$_.a}}, @{n="b";e={$_.b}}a b- -1 53 13 45 97 2
See answer by @Frode F. for a detailed explanation, but that answer does miss one situation. When the outer container only has one item (i.e. when the array only contains one hashtable), Sort-Object "conveniently" sorts the inner container.
So...Where $array.Count -eq 1
, the elements of that hashtable are sorted.Where $array.Count -gt 1
, the elements of the array are sorted.
As a workaround, use:
if ($array.Count -gt 1) { $result = Sort-Object { $_.a }, {$_.b }} else { $result = $array}