Hashtables and key order

后端 未结 7 1017
青春惊慌失措
青春惊慌失措 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:56

    You can give one sequential key as you add elements:

    $hashtable = @{}
    $hashtable[$hashtable.count] = @("Switzerland", "Bern")
    $hashtable[$hashtable.count] = @("Spain", "Madrid")
    $hashtable[$hashtable.count] = @("Italy", "Rome")
    $hashtable[$hashtable.count] = @("Germany", "Berlin")
    $hashtable
    

    Then, you can get elements sorted by the key:

    echo "`nHashtable keeping the order as they were added"
    foreach($item in $hashtable.getEnumerator() | Sort Key)
    {
        $item
    }
    
    0 讨论(0)
  • 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 {$_}
    
    0 讨论(0)
  • 2020-12-05 18:04

    Here is a simple routine that works for me.

    function sortedKeys([hashtable]$ht) {
      $out = @()
      foreach($k in $ht.keys) {
        $out += $k
      }
      [Array]::sort($out)
      return ,$out
    }
    

    and the call to use it

    forEach($k in (& sortedKeys $ht)) {
      ...
    }
    
    0 讨论(0)
  • 2020-12-05 18:04

    The PowerShell 1 way is to add a hashtable member to retain the add order. There is no need to use System.Collections.Specialized.OrderedDictionary:

    $Hash = New-Object PSObject                                       
    $Hash | Add-Member -MemberType NoteProperty -Name key1 -Value val1
    $Hash | Add-Member -MemberType NoteProperty -Name key2 -Value val2
    $Hash | Add-Member -MemberType NoteProperty -Name key3 -Value val3
    
    0 讨论(0)
  • 2020-12-05 18:09

    You can use an ordered dictionary instead:

    Like this:

    $list = New-Object System.Collections.Specialized.OrderedDictionary
    $list.Add("Switzerland", "Bern")
    $list.Add("Spain", "Madrid")
    $list.Add("Italy", "Rome")
    $list.Add("Germany", "Berlin")
    $list
    
    0 讨论(0)
  • 2020-12-05 18:13
    function global:sortDictionaryByKey([hashtable]$dictionary)
    {
        return $dictionary.GetEnumerator() | sort -Property name;
    }
    
    0 讨论(0)
提交回复
热议问题