35

追加されたキーの順序をハッシュテーブルに保持する方法はありますか?プッシュ/ポップメカニズムのように。

例:

$hashtable = @{}

$hashtable.Add("Switzerland", "Bern")
$hashtable.Add("Spain", "Madrid")
$hashtable.Add("Italy", "Rome")
$hashtable.Add("Germany", "Berlin")
$hashtable

ハッシュテーブルに要素を追加した順序を保持したいと思います。

4

7 に答える 7

60

PowerShell V1/V2には組み込みのソリューションはありません。.NETを使用することをお勧めします System.Collections.Specialized.OrderedDictionary

$order = New-Object System.Collections.Specialized.OrderedDictionary
$order.Add("Switzerland", "Bern")
$order.Add("Spain", "Madrid")
$order.Add("Italy", "Rome")
$order.Add("Germany", "Berlin")


PS> $order

Name                           Value
----                           -----
Switzerland                    Bern
Spain                          Madrid
Italy                          Rome
Germany                        Berlin

PowerShell V3では、[注文済み]にキャストできます。

PS> [ordered]@{"Switzerland"="Bern"; "Spain"="Madrid"; "Italy"="Rome"; "Germany"="Berlin"}

Name                           Value
----                           -----
Switzerland                    Bern
Spain                          Madrid
Italy                          Rome
Germany                        Berlin
于 2013-02-15T09:02:44.743 に答える
10

代わりに、順序付き辞書を使用できます。

このような:

$list = New-Object System.Collections.Specialized.OrderedDictionary
$list.Add("Switzerland", "Bern")
$list.Add("Spain", "Madrid")
$list.Add("Italy", "Rome")
$list.Add("Germany", "Berlin")
$list
于 2013-02-15T09:01:11.297 に答える
6

要素を追加するときに、1つのシーケンシャルキーを指定できます。

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

次に、キーで並べ替えられた要素を取得できます。

echo "`nHashtable keeping the order as they were added"
foreach($item in $hashtable.getEnumerator() | Sort Key)
{
    $item
}
于 2015-04-10T00:52:22.263 に答える
1

PowerShell 1の方法は、ハッシュテーブルメンバーを追加して、追加順序を保持することです。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
于 2013-09-01T11:33:29.053 に答える
1

古いバージョンのPowerShellとの互換性のために、次のコマンドレットを検討してください。

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
}

このコマンドレットは、関数定義順に並べられたキーのリストを返します。

名前順:

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

値で並べ替え:

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

ハッシュテーブルをネストすることも検討してください。

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

たとえば、(ハッシュされた)注文プロパティで並べ替えて、キー(国)を返します。

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

または、事前定義された大文字で並べ替え(降順)します。

$HashTable | Order-Keys {$_.Capital} -Descending | ForEach {$_}
于 2014-03-24T15:32:44.400 に答える
1

これが私のために働く簡単なルーチンです。

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

そしてそれを使用するための呼び出し

forEach($k in (& sortedKeys $ht)) {
  ...
}
于 2018-10-31T23:36:07.757 に答える
-1
function global:sortDictionaryByKey([hashtable]$dictionary)
{
    return $dictionary.GetEnumerator() | sort -Property name;
}
于 2018-08-30T22:42:04.550 に答える