Hashtables and key order

后端 未结 7 1044
青春惊慌失措
青春惊慌失措 2020-12-05 17:46

Is there a way to keep the order of keys in a hashtable as they were added? Like a push/pop mechanism.

Example:

$hashtable = @{}

$hashtable.Add(\"Sw         


        
7条回答
  •  情深已故
    2020-12-05 17:59

    For compatibility with older PowerShell versions you might consider this cmdlet:

    Function Order-Keys {
        param(
            [Parameter(Mandatory = $true, ValueFromPipeline = $true)][HashTable]$HashTable,
            [Parameter(Mandatory = $false, Position = 1)][ScriptBlock]$Function,
            [Switch]$Descending
        )
        $Keys = $HashTable.Keys | ForEach {$_} # Copy HashTable + KeyCollection
        For ($i = 0; $i -lt $Keys.Count - 1; $i++) {
            For ($j = $i + 1; $j -lt $Keys.Count; $j++) {
                $a = $Keys[$i]
                $b = $Keys[$j]
                If ($Function -is "ScriptBlock") {
                    $a = $HashTable[$a] | ForEach $Function
                    $b = $HashTable[$b] | ForEach $Function
                }
                If ($Descending) {
                    $Swap = $a -lt $b
                }
                Else
                {
                    $Swap = $a -gt $b
                }
                If ($Swap) {
                    $Keys[$i], $Keys[$j] = $Keys[$j], $Keys[$i]
                }
            }
        }
        Return $Keys
    }
    

    This cmdlet returns a list of keys ordered by the function definition:

    Sort by name:

    $HashTable | Order-Keys | ForEach {Write-Host $_ $HashTable[$_]}
    Germany Berlin
    Italy Rome
    Spain Madrid
    Switzerland Bern
    

    Sort by value:

    $HashTable | Order-Keys {$_} | ForEach {Write-Host $_ $HashTable[$_]}
    Germany Berlin
    Switzerland Bern
    Spain Madrid
    Italy Rome
    

    You might also consider to nest hash tables:

    $HashTable = @{
        Switzerland = @{Order = 1; Capital = "Berne"}
        Germany     = @{Order = 2; Capital = "Berlin"}
        Spain       = @{Order = 3; Capital = "Madrid"}
        Italy       = @{Order = 4; Capital = "Rome"}
    }
    

    E.g. sort by (hashed) order property and return the key (country):

    $HashTable | Order-Keys {$_.Order} | ForEach {$_}
    

    Or sort (descending) by the predefined capital:

    $HashTable | Order-Keys {$_.Capital} -Descending | ForEach {$_}
    

提交回复
热议问题