$theTitle=wp_title(" - ", false); if($theTitle != "") { ?>
About Virtualization, VDI, SBC, Application Compatibility and anything else I feel like
22 Jul // php the_time('Y') ?>
In a PowerShell script I needed to sort a hash table by byte value (not alphabetically, lowercase parameters will be listed after uppercase ones). An example for this requirement is the Amazon Product Advertising API.
Consider the following hashtable as an example:
1 2 3 4 5 | $params = @{} $params.Add("AssociateTag", "dummy") $params.Add("AWSAccessKeyId", "AKIAIOSFODNN7EXAMPLE") $params.Add("IdType", "0679722769") $params.Add("Operation", "ItemLookup") |
If we use the Sort-Object to order the list (note that we need to use the GetEnumerator method):
1 | $params.GetEnumerator() | Sort-Object Name |
We will get the following result:
1 2 3 4 5 6 | Name Value ---- ----- AssociateTag dummy AWSAccessKeyId AKIAIOSFODNN7EXAMPLE IdType 0679722769 Operation ItemLookup |
If you use the -CaseSensitive
switch the resulting order will remain the same.
I came up with the following code (download link below) to sort the hashtable in the required order:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | function Sort-Binary { param( [Parameter(Mandatory = $true, ValueFromPipeline = $true)][HashTable]$HashTable, [Switch]$Descending ) $keys = $HashTable.Keys | ForEach {$_} for ($i = 0; $i -lt $keys.Count - 1; $i++) { for ($j = $i + 1; $j -lt $keys.Count; $j++) { if ($Descending) {$swap = [String]::CompareOrdinal($keys[$i], $keys[$j]) -lt 0} else {$swap = [String]::CompareOrdinal($keys[$i], $keys[$j]) -gt 0} if ($swap) {$keys[$i], $keys[$j] = $keys[$j], $keys[$i]} } } $list = New-Object System.Collections.Specialized.OrderedDictionary $keys | ForEach { $list.Add($_, $HashTable[$_]) } return $list } |
Let’s try that:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | $params = @{} $params.Add("AssociateTag", "dummy") $params.Add("AWSAccessKeyId", "AKIAIOSFODNN7EXAMPLE") $params.Add("IdType", "0679722769") $params.Add("Operation", "ItemLookup") $params | Sort-Binary Name Value ---- ----- AWSAccessKeyId AKIAIOSFODNN7EXAMPLE AssociateTag dummy IdType 0679722769 Operation ItemLookup |
4 Responses for "Sorting a hashtable by byte value in PowerShell"
Hi Remko,
After some digging in System.Text a.o., this does the same thing (add sortkey to output to see what is sorts on)
$params.GetEnumerator() | sort @{e={ $_ | Add-Member -MemberType ‘NoteProperty’ -Name ‘SortKey’ -Value ([System.BitConverter]::ToString( [system.Text.Encoding]::ASCII.GetBytes( $_.Name))) }}, SortKey
Hi Michel, I tried to get something working using a Sort Expression but I had not thought of this approach. Very clever, like this better than my approach actually.
There’s a .NET class called SortedDictionary which does this work for you, if you prefer. You just need to tell it what kind of comparison to perform (in this case, the built-in StringComparer.Ordinal class):
$params = New-Object -TypeName ‘System.Collections.Generic.SortedDictionary[string,object]’ -ArgumentList ([System.StringComparer]::Ordinal)
$params.Add(“AssociateTag”, “dummy”)
$params.Add(“AWSAccessKeyId”, “AKIAIOSFODNN7EXAMPLE”)
$params.Add(“IdType”, “0679722769”)
$params.Add(“Operation”, “ItemLookup”)
$params
That’s nice Dave, .NET FrameWork is full of hidden gems. Thanks for adding that!
Leave a reply