I'm having an issue sorting a hash table. I've broken down my code to just bare necessities so as not to overwhelm anyone with my original script.
Write-Host "PowerShell Version = " ([string]$psversiontable.psversion)
$h = @{}
$Value = @{SortOrder=1;v1=1;}
$h.Add(1, $Value)
$Value = @{SortOrder=2;v1=1;}
$h.Add(2, $Value)
$Value = @{SortOrder=3;v1=1;}
$h.Add(3, $Value)
$Value = @{SortOrder=4;v1=1;}
$h.Add(4, $Value)
Write-Host "Ascending"
foreach($f in $h.GetEnumerator() | Sort-Object Value.SortOrder)
{
Write-Host $f.Value.SortOrder
}
Write-Host "Descending"
foreach($f in $h.GetEnumerator() | Sort-Object Value.SortOrder -descending)
{
Write-Host $f.Value.SortOrder
}
The output is
PowerShell Version = 3.0
Ascending
2
1
4
3
Descending
2
1
4
3
I'm sure this is just a simple case of not knowing the correct usage of Sort-Object
. The sort works correctly on Sort-Object Name
so maybe it has something to do with not knowing how to handle the Value.SortOrder
?
Before moving forward, we need to understand that it is not possible to sort a Hashtable since the data is stored by the hashcode of the key, not by the index . So to sort the data of a Hashtable, we need to have a sortable object like an array or an ArrayList. Sorting has to be done on Key or Value.
To sort the output in the PowerShell you need to use Sort-Object Pipeline cmdlet. In the below example, we will retrieve the output from the Get-Process command and we will sort the, according to memory and CPU usage.
There are actually two ways to do this. The first way to do this is to use the Sort-Object cmdlet (Sort is an alias for the Sort-Object cmdlet). The second way to sort an array is to use the static Sort method from the System. Array .
Hashtable is a data structure that stores data in key-value format. The stored data is neither in sorted order nor preserves the insertion order.
Sort-Object accepts a property name or a script block used to sort. Since you're trying to sort on a property of a property, you'll need to use a script block:
Write-Host "Ascending"
$h.GetEnumerator() |
Sort-Object { $_.Value.SortOrder } |
ForEach-Object { Write-Host $_.Value.SortOrder }
Write-Host "Descending"
$h.GetEnumerator() |
Sort-Object { $_.Value.SortOrder } -Descending |
ForEach-Object { Write-Host $_.Value.SortOrder }
You can filter using the Where-Object cmdlet:
Write-Host "Ascending"
$h.GetEnumerator() |
Where-Object { $_.Name -ge 2 } |
Sort-Object { $_.Value.SortOrder } |
ForEach-Object { Write-Host $_.Value.SortOrder }
You usually want to put Where-Object
before any Sort-Object
cmdlets, since it makes sorting faster.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With