次の方法で共有


about_Hash_Tables

簡単な説明

PowerShell でハッシュテーブルを作成、使用、並べ替える方法について説明します。

詳細な説明

hashtable (ディクショナリ配列または連想配列とも呼ばれます) は、1 つ以上のキーと値のペアを格納するコンパクトなデータ構造です。 たとえば、ハッシュ テーブルには一連の IP アドレスとコンピューター名が含まれている場合があります。ここで、IP アドレスはキー、コンピューター名は値、またはその逆です。

PowerShell では、各 hashtable は [System.Collections.Hashtable] オブジェクトです。 PowerShell では、 Hashtable オブジェクトのプロパティとメソッドを使用できます。

PowerShell 3.0 以降では、 [ordered] 型アクセラレータを使用して、PowerShell で [System.Collections.Specialized.OrderedDictionary] オブジェクトを作成できます。

順序付けされたディクショナリは、キーが常に一覧表示される順序で表示されるという点でハッシュテーブルとは異なります。 hashtable内のキーの順序は決定論的ではありません。

ハッシュテーブルのキーと値も .NET オブジェクトです。 ほとんどの場合、文字列または整数ですが、任意のオブジェクト型を持つことができます。 キーの値が別の hashtableである入れ子になったハッシュテーブルを作成することもできます。

ハッシュテーブルは、データの検索と取得に効率的であるため、頻繁に使用されます。 ハッシュテーブルを使用すると、リストを格納したり、PowerShell で計算プロパティを作成したりできます。 また、 ConvertFrom-StringData コマンドレットは、構造化文字列データを hashtableに変換します。

構文

hashtableの構文は次のとおりです。

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

順序付けられたディクショナリの構文は次のとおりです。

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

[ordered] 型アクセラレータは、PowerShell 3.0 で導入されました。

hashtableを作成するには、次のガイドラインに従います。

  • アット マーク (@) でhashtableを開始します。
  • hashtableを中かっこ ({}) で囲みます。
  • hashtableの内容に対して 1 つ以上のキーと値のペアを入力します。
  • 等号 (=) を使用して、各キーをその値から分離します。
  • セミコロン (;) または改行を使用して、キーと値のペアを区切ります。
  • スペースを含むキーは引用符で囲む必要があります。 値は有効な PowerShell 式である必要があります。 文字列にはスペースが含まれていない場合でも、引用符で囲む必要があります。
  • hashtableを管理するには、変数に保存します。
  • 順序付けられたhashtableを変数に割り当てるときは、@記号の前に[ordered]型を配置します。 変数名の前に配置すると、コマンドは失敗します。

ハッシュテーブルを使用するのと同じ方法で、順序付きディクショナリを使用できます。 どちらの型も、 hashtable またはディクショナリ (iDictionary) 型オブジェクトを受け取るパラメーターの値として使用できます。

ハッシュテーブルと順序付きディクショナリの作成

次の hashtable および順序付きディクショナリの例を考えてみましょう。

$hash = @{
    1       = 'one'
    2       = 'two'
    'three' = 3
}
$hash
Name                           Value
----                           -----
three                          3
2                              two
1                              one

ご覧のように、 hashtable のキーと値のペアは、定義された順序では表示されません。

順序付けされたディクショナリを作成する最も簡単な方法は、 [ordered] 属性を使用する方法です。 属性を @ 記号の直前に配置します。

$dictionary = [ordered]@{
    1       = 'one'
    2       = 'two'
    'three' = 3
}
$dictionary
Name                           Value
----                           -----
1                              one
2                              two
three                          3

ハッシュテーブルとは異なり、順序付けされたディクショナリはキーと値の順序を維持します。

ハッシュテーブルと順序付きディクショナリの変換

[ordered]型アクセラレータを使用してhashtableを変換またはキャストすることはできません。 変数名の前に順序付けされた属性を配置すると、コマンドは失敗し、次のエラー メッセージが表示されます。

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

式を修正するには、[ordered] 属性を移動します。

$orderedhash = [ordered]@{}

順序指定されたディクショナリを hashtableにキャストすることはできますが、メンバーの順序を保証することはできません。

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

Hashtable およびディクショナリのプロパティ

ハッシュテーブルと順序付けられたディクショナリは、いくつかのプロパティを共有します。 前の例で定義した $hash 変数と $dictionary 変数について考えてみましょう。

$hash | Get-Member -MemberType Properties, ParameterizedProperty
   TypeName: System.Collections.Hashtable

Name           MemberType            Definition
----           ----------            ----------
Item           ParameterizedProperty System.Object Item(System.Object key) {get;set;}
Count          Property              int Count {get;}
IsFixedSize    Property              bool IsFixedSize {get;}
IsReadOnly     Property              bool IsReadOnly {get;}
IsSynchronized Property              bool IsSynchronized {get;}
Keys           Property              System.Collections.ICollection Keys {get;}
SyncRoot       Property              System.Object SyncRoot {get;}
Values         Property              System.Collections.ICollection Values {get;}
$dictionary | Get-Member -MemberType Properties, ParameterizedProperty
   TypeName: System.Collections.Specialized.OrderedDictionary

Name           MemberType            Definition
----           ----------            ----------
Item           ParameterizedProperty System.Object Item(int index) {get;set;},
                                     System.Object Item(System.Object key) {get;set;}
Count          Property              int Count {get;}
IsFixedSize    Property              bool IsFixedSize {get;}
IsReadOnly     Property              bool IsReadOnly {get;}
IsSynchronized Property              bool IsSynchronized {get;}
Keys           Property              System.Collections.ICollection Keys {get;}
SyncRoot       Property              System.Object SyncRoot {get;}
Values         Property              System.Collections.ICollection Values {get;}

最も使用されるプロパティは、 CountKeysValues、および Item です。

  • オブジェクト内のキーと値のペアの数を示す Count プロパティ。

  • Keys プロパティは、hashtableまたはディクショナリ内のキー名のコレクションです。

    PS> $hash.Keys
    three
    2
    1
    
    PS> $dictionary.Keys
    1
    2
    three
    
  • Values プロパティは、hashtableまたはディクショナリ内の値のコレクションです。

    PS> $hash.Values
    3
    two
    one
    
    PS> $dictionary.Values
    one
    two
    3
    
  • Item プロパティは、指定した項目の値を返すパラメーター化されたプロパティです。 ハッシュテーブルでは、パラメーター化されたプロパティのパラメーターとしてキーが使用されますが、ディクショナリでは既定でインデックスが使用されます。 この違いは、各型の値にアクセスする方法に影響します。

値へのアクセス

hashtableまたはディクショナリ内の値にアクセスするには、メンバー表記と配列インデックス表記の 2 つの一般的な方法があります。

  • メンバー表記 - オブジェクトのメンバー プロパティとしてキー名を使用して値にアクセスできます。 次に例を示します。

    PS> $hash.1
    one
    
    PS> $dictionary.2
    two
    
  • 配列インデックス表記 - インデックス表記を使用して値にアクセスできます。 PowerShell は、その表記をオブジェクトのパラメーター化されたプロパティ Item の呼び出しに変換します。

    ハッシュテーブルでインデックス表記を使用する場合、角かっこ内の値はキー名です。 キーが文字列値の場合は、キー名を引用符で囲みます。 次に例を示します。

    PS> $hash['three']
    3
    
    PS> $hash[2]
    2
    

    この例では、 2 キー値は値のコレクションのインデックスではありません。 これは、キーと値のペアのキーの値です。 これは、値のコレクションにインデックスを作成することで証明できます。

    PS> ([array]$hash.Values)[2]
    one
    

    辞書でインデックス表記を使用すると、角かっこ内の値はその型に基づいて解釈されます。 値が整数の場合は、値のコレクションのインデックスとして扱われます。 値が整数でない場合は、キー名として扱われます。 次に例を示します。

    PS> $dictionary[1]
    two
    PS> ([array]$dictionary.Values)[1]
    two
    PS> $dictionary[[object]1]
    one
    PS> $dictionary['three']
    3
    

    この例では、 [1] 配列値は、パラメーター化されたプロパティ オーバーロード Item(int index) 使用した値のコレクション内のインデックスです。 [[object]1]配列値はインデックスではなく、Item(System.Object key)オーバーロードを使用するキー値です。

    Note

    この動作は、キー値が整数の場合に混乱を招く可能性があります。 可能な場合は、ディクショナリで整数キー値を使用しないようにする必要があります。

プロパティ名の競合の処理

キー名が HashTable 型のいずれかのプロパティ名と競合する場合は、 psbase intrinsic メンバー を使用してこれらのプロパティにアクセスできます。 たとえば、キー名が keys で、 HashTable キーのコレクションを返す場合は、次の構文を使用します。

$hashtable.psbase.Keys

この要件は、OrderedDictionaryなど、System.Collections.IDictionary インターフェイスを実装する他の型に適用されます。

キーと値の反復処理

hashtable内のキーを反復処理して、いくつかの方法で値を処理できます。 このセクションの各例の出力は同じです。 ここで定義されている $hash 変数を反復処理します。

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

Note

これらの例では、 $hash は、出力が常に同じ順序になるように順序付けされたディクショナリとして定義されています。 これらの例は標準ハッシュテーブルでも同じように動作しますが、出力の順序は予測できません。

各例では、すべてのキーとその値に対してメッセージが返されます。

The value of 'Number' is: 1
The value of 'Shape' is: Square
The value of 'Color' is: Blue

この例では、 foreach ブロックを使用してキーを反復処理します。

foreach ($Key in $hash.Keys) {
    "The value of '$Key' is: $($hash[$Key])"
}

この例では、 ForEach-Object を使用してキーを反復処理します。

$hash.Keys | ForEach-Object {
    "The value of '$_' is: $($hash[$_])"
}

この例では、 GetEnumerator() メソッドを使用して、各キーと値のペアをパイプライン経由で送信して ForEach-Objectします。

$hash.GetEnumerator() | ForEach-Object {
    "The value of '$($_.Key)' is: $($_.Value)"
}

この例では、 GetEnumerator() メソッドと ForEach() メソッドを使用して、各キーと値のペアを反復処理します。

$hash.GetEnumerator().ForEach({"The value of '$($_.Key)' is: $($_.Value)"})

キーと値の追加と削除

通常、 hashtable を作成するときは、キーと値のペアを定義に含めます。 ただし、 hashtable のキーと値のペアはいつでも追加および削除できます。 次の例では、空の hashtableを作成します。

$hash = @{}

配列表記を使用してキーと値のペアを追加できます。 たとえば、次の例では、値が NowTime キーをhashtableに追加します。

$hash["Time"] = "Now"

System.Collections.Hashtable オブジェクトの Add() メソッドを使用して、キーと値をhashtableに追加することもできます。 Add() メソッドには次の構文があります。

Add(Key, Value)

たとえば、値が NowTime キーをhashtableに追加するには、次のステートメント形式を使用します。

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

また、加算演算子 (+) を使用してキーと値をhashtableに追加して、既存のhashtableにhashtableを追加できます。 たとえば、次のステートメントでは、$hash 変数のhashtableにNowの値を持つTime キーを追加します。

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

変数に格納されている値を追加することもできます。

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

$hash.Add($t, $now)

減算演算子を使用してハッシュ テーブルからキーと値のペアを削除することはできませんが、hashtable オブジェクトのRemove()メソッドを使用できます。 Remove メソッドには次の構文があります。

$object.Remove(<key>)

次の例では、 Time キーと値のペアを $hashから削除します。

$hash.Remove("Time")

HashTable のオブジェクト型

hashtableのキーと値には任意の .NET オブジェクト型を指定でき、1 つのhashtableには複数の型のキーと値を含めることができます。

次のステートメントは、プロセス名文字列とプロセス オブジェクト値の hashtable を作成し、 $p 変数に保存します。

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

$pにhashtableを表示し、キー名プロパティを使用して値を表示できます。

PS> $p

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

PS> $p.PowerShell

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

PS> $p.keys | ForEach-Object {$p.$_.handles}
441
251

hashtableのキーには、任意の .NET 型を指定できます。 次のステートメントは、$p変数のhashtableにキーと値のペアを追加します。 キーは、WinRM サービスを表す Service オブジェクトであり、値はサービスの現在の状態です。

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

hashtable内の他のペアに使用するのと同じ方法を使用して、新しいキーと値のペアを表示およびアクセスできます。

PS> $p

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

PS> $p.keys
PowerShell
Notepad

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

PS> $p.keys | ForEach-Object {$_.name}
WinRM

hashtable内のキーと値は、オブジェクトHashtableすることもできます。 次のステートメントは、キーが文字列 Hash2 である$p変数のhashtableにキーと値のペアを追加します。値は 3 つのキーと値のペアを持つhashtableです。

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

同じメソッドを使用して、新しい値を表示およびアクセスできます。

PS> $p

Name                           Value
----                           -----
PowerShell                     System.Diagnostics.Process (pwsh)
Hash2                          {[a, 1], [b, 2], [c, 3]}
Notepad                        System.Diagnostics.Process (Notepad)
WinRM                          Running

PS> $p.Hash2

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

PS> $p.Hash2.b
2

キーと値の並べ替え

hashtable内の項目は本質的に順序付けされません。 キーと値のペアは、表示するたびに異なる順序で表示される場合があります。

hashtableを並べ替えることはできませんが、ハッシュテーブルのGetEnumerator()メソッドを使用してキーと値を列挙し、Sort-Object コマンドレットを使用して表示の列挙値を並べ替えることができます。

たとえば、次のコマンドは、 $p 変数のハッシュ テーブル内のキーと値を列挙し、キーをアルファベット順に並べ替えます。

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

Name                           Value
----                           -----
Hash2                          {[a, 1], [b, 2], [c, 3]}
Notepad                        System.Diagnostics.Process (Notepad)
PowerShell                     System.Diagnostics.Process (pwsh)
WinRM                          Running

次のコマンドでは、同じ手順を使用してハッシュ値を降順に並べ替えます。

PS> $p.GetEnumerator() | Sort-Object -Property Value -Descending

Name                           Value
----                           -----
PowerShell                     System.Diagnostics.Process (pwsh)
Notepad                        System.Diagnostics.Process (Notepad)
Hash2                          {[a, 1], [b, 2], [c, 3]}
WinRM                          Running

ハッシュテーブルからのオブジェクトの作成

PowerShell 3.0 以降では、プロパティとプロパティ値の hashtable からオブジェクトを作成できます。

構文は次のとおりです。

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

このメソッドは、パラメーターのないコンストラクターを持つクラスに対してのみ機能します。 オブジェクトのプロパティは、パブリックで設定可能である必要があります。

詳細については、「 about_Object_Creation」を参照してください。

ConvertFrom-StringData

ConvertFrom-StringData コマンドレットは、キーと値のペアの文字列またはここの文字列をhashtableに変換します。 スクリプトの [データ] セクションで ConvertFrom-StringData コマンドレットを安全に使用できます。また、 Import-LocalizedData コマンドレットと共に使用して、現在のユーザーのユーザー インターフェイス (UI) カルチャにユーザー メッセージを表示できます。

この文字列は、 hashtable の値に引用符が含まれている場合に特に便利です。 here-strings の詳細については、 about_Quoting_Rulesを参照してください。

次の例は、前の例でユーザー メッセージの文字列を作成する方法と、 ConvertFrom-StringData を使用して文字列から hashtableに変換する方法を示しています。

次のコマンドは、キーと値のペアの here 文字列を作成し、 $string 変数に保存します。

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

このコマンドでは、 ConvertFrom-StringData コマンドレットを使用して、この文字列を hashtableに変換します。

ConvertFrom-StringData $string

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

here-strings の詳細については、 about_Quoting_Rulesを参照してください。

関連項目