Share via


about_Hash_Tables

簡短描述

描述如何在PowerShell中建立、使用及排序哈希表。

完整描述

哈希表也稱為字典或關聯數位,是儲存一或多個索引鍵/值組的精簡數據結構。 例如,哈希表可能包含一系列的IP位址和計算機名稱,其中IP位址是密鑰,而電腦名稱是值,反之亦然。

在 PowerShell 中,每個哈希表都是 (System.Collections.Hashtable) 物件的 Hashtable。 您可以在 PowerShell 中使用 Hashtable 物件的屬性和方法。

從 PowerShell 3.0 開始,您可以使用 [ordered] 屬性,在 PowerShell 中建立已排序的字典 (System.Collections.Specialized.OrderedDictionary) 。

已排序的字典與哈希表不同,因為索引鍵一律會以您列出它們的順序顯示。 哈希表中的索引鍵順序不會決定。

哈希表中的索引鍵和值也是 .NET 物件。 它們通常是字串或整數,但可以有任何物件類型。 您也可以建立巢狀哈希表,其中索引鍵的值是另一個哈希表。

經常使用哈希表,因為它們非常有效率地尋找和擷取數據。 您可以使用哈希表來儲存清單,並在PowerShell中建立匯出屬性。 而PowerShell有 Cmdlet ConvertFrom-StringData,可將字串轉換成哈希表。

Syntax

哈希表的語法如下所示:

@{ <name> = <value>; [<name> = <value> ] ...}

已排序字典的語法如下所示:

[ordered]@{ <name> = <value>; [<name> = <value> ] ...}

PowerShell 3.0 中引進 [已排序] 屬性。

建立哈希表

若要建立哈希表,請遵循下列指導方針:

  • 以符號 () @ 開始哈希表。
  • 將哈希表括在大括弧 ({}) 。
  • 輸入哈希表內容的一或多個索引鍵/值組。
  • 使用等號 (=) 來分隔每個索引鍵與其值。
  • 使用分號 (;) 或換行符來分隔索引鍵/值組。
  • 包含空格的索引鍵必須以引號括住。 值必須是有效的 PowerShell 表達式。 即使字串不包含空格,字串也必須以引號顯示。
  • 若要管理哈希表,請將它儲存在變數中。
  • 將已排序的哈希表指派給變數時,請將 [已排序] 屬性放在符號之前 @ 。 如果您在變數名稱之前放置它,命令就會失敗。

若要在 $hash 的值中建立空的哈希表,請輸入:

$hash = @{}

當您建立索引鍵和值時,您也可以將索引鍵和值新增至哈希表。 例如,下列語句會建立具有三個索引鍵的哈希表。

$hash = @{ Number = 1; Shape = "Square"; Color = "Blue"}

建立已排序的字典

您可以藉由新增 OrderedDictionary 類型的物件來建立已排序的字典,但建立已排序字典的最簡單方式是使用 [ordered] 屬性。

屬性 [ordered] 是在 PowerShell 3.0 中引進。

將屬性放在 「@」 符號前面。

$hash = [ordered]@{ Number = 1; Shape = "Square"; Color = "Blue"}

您可以使用與使用哈希表相同的方式來使用已排序的字典。 任一類型都可以當做接受哈希表或字典的參數值, (iDictionary) 。

您無法使用 [ordered] 屬性來轉換或轉換哈希表。 如果您在變數名稱之前放置已排序的屬性,命令會失敗,並出現下列錯誤訊息。

[ordered]$hash = @{}
ParserError:
Line |
   1 |  [ordered]$hash = @{}
     |  ~~~~~~~~~~~~~~
     | The ordered attribute can be specified only on a hash literal node.

若要更正表示式,請移動 [已排序] 屬性。

$hash = [ordered]@{}

您可以將已排序的字典轉換成哈希表,但即使清除變數並輸入新的值,您也無法復原已排序的屬性。 若要重新建立順序,您必須移除並重新建立變數。

[hashtable]$hash = [ordered]@{
  Number = 1; Shape = "Square"; Color = "Blue"}
$hash
Name                           Value
----                           -----
Color                          Blue
Shape                          Square
Number                         1

顯示哈希表

若要顯示儲存在變數中的哈希表,請輸入變數名稱。 根據預設,哈希表會顯示為數據表,其中一個數據行用於索引鍵,另一個用於值。

$hash
Name                           Value
----                           -----
Shape                          Square
Color                          Blue
Number                         1

哈希錶具有索引鍵和值屬性。 使用點表示法來顯示所有索引鍵或所有值。

$hash.keys
Number
Shape
Color
$hash.values
1
Square
Blue

每個索引鍵名稱也是哈希表的屬性,而其值則是索引鍵名稱屬性的值。 使用下列格式來顯示屬性值。

$hashtable.<key>
<value>

例如:

$hash.Number
1

$hash.Color
Blue

如果索引鍵名稱與 HashTable 類型的其中一個屬性名稱衝突,您可以使用 PSBase 來存取這些屬性。 例如,如果索引鍵名稱是 keys 且您想要傳回 Keys 的集合,請使用下列語法:

$hashtable.PSBase.Keys

哈希表具有 Count 屬性,指出哈希表中索引鍵/值組的數目。

$hash.count
3

哈希表數據表不是陣列,因此您無法使用整數做為哈希表的索引,但您可以使用索引鍵名稱來編制哈希表的索引。 如果索引鍵是字串值,請以引號括住索引鍵名稱。

例如:

$hash["Number"]
1

新增和移除索引鍵和值

若要將索引鍵和值新增至哈希表,請使用下列命令格式。

$hash["<key>"] = "<value>"

例如,若要將值為 「Now」 的 「Time」 索引鍵新增至哈希表,請使用下列語句格式。

$hash["Time"] = "Now"

您也可以使用 System.Collections.Hashtable 物件的 Add 方法,將索引鍵和值新增至哈希表。 Add 方法具有下列語法:

Add(Key, Value)

例如,若要將值為 「Now」 的 「Time」 索引鍵新增至哈希表,請使用下列語句格式。

$hash.Add("Time", "Now")

此外,您可以使用加法運算符將索引鍵和值新增至哈希表, (+) 將哈希表新增至現有的哈希表。 例如,下列語句會將值為 “Now” 的 “Time” 索引鍵新增至$hash變數中的哈希表。

$hash = $hash + @{Time="Now"}

您也可以新增儲存在變數中的值。

$t = "Today"
$now = (Get-Date)

$hash.Add($t, $now)

您無法使用減法運算符從哈希表移除索引鍵/值組,但您可以使用Hashtable物件的Remove方法。 Remove 方法會採用索引鍵做為其值。

Remove 方法具有下列語法:

Remove(Key)

例如,若要從$hash變數值中的哈希數據表中移除 Time=Now 索引鍵/值組,請輸入:

$hash.Remove("Time")

您可以在 PowerShell 中使用 Hashtable 物件的所有屬性和方法,包括 Contains、Clear、Clone 和 CopyTo。 如需Hashtable對象的詳細資訊,請參閱 System.Collections.Hashtable

HashTable 中的物件類型

哈希表中的索引鍵和值可以有任何 .NET 物件類型,而單一哈希表可以具有多個類型的索引鍵和值。

下列語句會建立進程名稱字串和進程物件值的哈希表,並將它儲存在變數中 $p

$p = @{"PowerShell" = (Get-Process PowerShell);
"Notepad" = (Get-Process notepad)}

您可以在 中 $p 顯示哈希表,並使用索引鍵名稱屬性來顯示值。

$p

Name                           Value
----                           -----
PowerShell                     System.Diagnostics.Process (PowerShell)
Notepad                        System.Diagnostics.Process (notepad)

$p.PowerShell

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
    441      24    54196      54012   571     5.10   1788 PowerShell

$p.keys | foreach {$p.$_.handles}
441
251

哈希表中的索引鍵也可以是任何 .NET 類型。 下列語句會將索引鍵/值組新增至變數中的 $p 哈希表。 索引鍵是代表 WinRM 服務的 Service 物件,值是服務的目前狀態。

$p = $p + @{(Get-Service WinRM) = ((Get-Service WinRM).Status)}

您可以使用哈希表中其他配對所使用的相同方法,來顯示及存取新的索引鍵/值組。

$p

Name                           Value
----                           -----
PowerShell                     System.Diagnostics.Process (PowerShell)
Notepad                        System.Diagnostics.Process (notepad)
System.ServiceProcess.Servi... Running

$p.keys
PowerShell
Notepad

Status   Name               DisplayName
------   ----               -----------
Running  winrm              Windows Remote Management (WS-Manag...

$p.keys | foreach {$_.name}
winrm

哈希表中的索引鍵和值也可以是Hashtable物件。 下列語句會將索引鍵/值組新增至變數中的 $p 索引鍵/值組,其中索引鍵為字串、Hash2,而此值是具有三個索引鍵/值組的哈希表。

$p = $p + @{"Hash2"= @{a=1; b=2; c=3}}

您可以使用相同的方法來顯示和存取新的值。

$p

Name                           Value
----                           -----
PowerShell                     System.Diagnostics.Process (PowerShell)
Notepad                        System.Diagnostics.Process (notepad)
System.ServiceProcess.Servi... Running
Hash2                          {a, b, c}

$p.Hash2

Name                           Value
----                           -----
a                              1
b                              2
c                              3

$p.Hash2.b
2

排序索引鍵和值

哈希表中的項目本質上是未排序的。 每次顯示索引鍵/值組時,可能會以不同的順序顯示。

雖然您無法排序哈希表,但是您可以使用哈希表的 GetEnumerator 方法來列舉索引鍵和值,然後使用 Sort-Object Cmdlet 來排序列舉值以供顯示。

例如,下列命令會列舉變數中哈希表中 $p 的索引鍵和值,然後依字母順序排序索引鍵。

$p.GetEnumerator() | Sort-Object -Property key

Name                           Value
----                           -----
Notepad                        System.Diagnostics.Process (notepad)
PowerShell                     System.Diagnostics.Process (PowerShell)
System.ServiceProcess.Servi... Running

下列命令會使用相同的程式,以遞減順序排序哈希值。

$p.getenumerator() | Sort-Object -Property Value -Descending

Name                           Value
----                           -----
PowerShell                     System.Diagnostics.Process (PowerShell)
Notepad                        System.Diagnostics.Process (notepad)
System.ServiceProcess.Servi... Running

從哈希表建立物件

從 PowerShell 3.0 開始,您可以從屬性和屬性值的哈希表建立物件。

語法如下:

[<class-name>]@{
  <property-name>=<property-value>
  <property-name>=<property-value>
}

這個方法只適用於具有 null 建構函式 (也就是沒有參數的建構函式) 的類別。 物件屬性必須是公用而且可設定。

如需詳細資訊,請參閱 about_Object_Creation

ConvertFrom-StringData

Cmdlet 會將 ConvertFrom-StringData 字串或索引鍵/值組的這裡字串轉換成哈希表。 您可以在腳本的 [數據] 區段中安全地使用 ConvertFrom-StringData Cmdlet,也可以搭配 Import-LocalizedData Cmdlet 在使用者介面 (UI 中顯示使用者訊息,) 目前使用者的文化特性。

當哈希表中的值包含引號時,這裡字串特別有用。 如需這裡字串的詳細資訊,請參閱 about_Quoting_Rules

下列範例示範如何在上一個範例中建立使用者訊息的這裡字串,以及如何用來 ConvertFrom-StringData 從字串轉換成哈希表。

下列命令會建立索引鍵/值組的這裡字串,然後將它儲存在變數中 $string

$string = @"
Msg1 = Type "Windows".
Msg2 = She said, "Hello, World."
Msg3 = Enter an alias (or "nickname").
"@

此命令會 ConvertFrom-StringData 使用 Cmdlet 將 here-string 轉換成哈希表。

ConvertFrom-StringData $string

Name                           Value
----                           -----
Msg3                           Enter an alias (or "nickname").
Msg2                           She said, "Hello, World."
Msg1                           Type "Windows".

如需這裡字串的詳細資訊,請參閱 about_Quoting_Rules

另請參閱