about_Hash_Tables

Kort beskrivning

Beskriver hur du skapar, använder och sorterar hashtabeller i PowerShell.

Lång beskrivning

En hashtable, även kallad ordlista eller associativ matris, är en kompakt datastruktur som lagrar ett eller flera nyckel/värde-par. En hash-tabell kan till exempel innehålla en serie IP-adresser och datornamn, där IP-adresserna är nycklarna och datornamnen är värdena, eller tvärtom.

I PowerShell är var och hashtable en ett objekt [System.Collections.Hashtable] . Du kan använda egenskaperna och metoderna för Hashtable objekt i PowerShell.

Från och med PowerShell 3.0 kan du använda [ordered] typacceleratorn för att skapa ett [System.Collections.Specialized.OrderedDictionary] objekt i PowerShell.

Ordnade ordlistor skiljer sig från hashtables eftersom nycklarna alltid visas i den ordning som du listar dem. Ordningen på nycklar i en hashtable är inte deterministisk.

Nycklarna och värdet i hashtables är också .NET-objekt. De är oftast strängar eller heltal, men de kan ha vilken objekttyp som helst. Du kan också skapa kapslade hashtables, där värdet för en nyckel är en annan hashtable.

Hashtables används ofta eftersom de är effektiva för att hitta och hämta data. Du kan använda hashtables för att lagra listor och skapa beräknade egenskaper i PowerShell. Och cmdleten ConvertFrom-StringData konverterar strukturerade strängdata till en hashtable.

Syntax

Syntaxen för en hashtable är följande:

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

Syntaxen för en ordnad ordlista är följande:

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

Typacceleratorn [ordered] introducerades i PowerShell 3.0.

Följ dessa riktlinjer för att skapa en hashtable:

  • hashtable Börja med ett vidtecken (@).
  • Omsluta hashtable klammerparenteserna ({}).
  • Ange ett eller flera nyckel/värde-par för innehållet i hashtable.
  • Använd ett likhetstecken (=) för att skilja varje nyckel från dess värde.
  • Använd ett semikolon (;) eller en radbrytning för att separera nyckel/värde-paren.
  • Nycklar som innehåller blanksteg måste omges av citattecken. Värden måste vara giltiga PowerShell-uttryck. Strängar måste visas inom citattecken, även om de inte innehåller blanksteg.
  • Om du vill hantera hashtablesparar du den i en variabel.
  • När du tilldelar en ordnad hashtable till en variabel placerar du [ordered] typen före symbolen @ . Om du placerar den före variabelnamnet misslyckas kommandot.

Du kan använda ordnade ordlistor på samma sätt som du använder hashtables. Antingen typ kan användas som värdet för parametrar som tar ett hashtable eller ordlistetypobjekt.iDictionary

Skapa hashtables och ordnade ordlistor

Överväg följande hashtable och ordnade ordlisteexempel:

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

Som du ser visas inte nyckel/värde-paren i en hashtable i den ordning de har definierats.

Det enklaste sättet att skapa en ordnad ordlista är att använda attributet [ordered] . Placera attributet omedelbart före symbolen @ .

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

Till skillnad från hashtables behåller ordnade ordlistor nyckelvärdets ordning.

Konvertera hashtables och ordnade ordlistor

Du kan inte använda [ordered] typacceleratorn för att konvertera eller omvandla en hashtable. Om du placerar det ordnade attributet före variabelnamnet misslyckas kommandot med följande felmeddelande.

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

Om du vill korrigera uttrycket flyttar du attributet [ordnat].

$orderedhash = [ordered]@{}

Du kan omvandla en ordnad ordlista till en hashtable, men du kan inte garantera ordningen på medlemmarna.

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

Hashtable och ordlisteegenskaper

Hashtables och ordnade ordlistor delar flera egenskaper. Överväg variablerna $hash och $dictionary som definierats i föregående exempel.

$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;}

De mest använda egenskaperna är Antal, Nycklar, Värden och Objekt.

  • Egenskapen Count som anger antalet nyckel/värde-par i objektet.

  • Egenskapen Nycklar är en samling med nyckelnamnen hashtable i ordlistan eller .

    PS> $hash.Keys
    three
    2
    1
    
    PS> $dictionary.Keys
    1
    2
    three
    
  • Egenskapen Värden är en samling värden i hashtable ordlistan eller .

    PS> $hash.Values
    3
    two
    one
    
    PS> $dictionary.Values
    one
    two
    3
    
  • Egenskapen Item är en parameteriserad egenskap som returnerar värdet för det objekt som du anger. Hashtables använder nyckeln som parameter för den parameteriserade egenskapen, medan ordlistor använder indexet som standard. Den här skillnaden påverkar hur du kommer åt värdena för varje typ.

Åtkomst till värden

Det finns två vanliga sätt att komma åt värdena i en hashtable eller en ordlista: medlems notation eller matrisindex notation.

  • Medlems notation – Värden kan nås med hjälp av nyckelnamnet som en medlemsegenskap för objektet. Till exempel:

    PS> $hash.1
    one
    
    PS> $dictionary.2
    two
    
  • Matrisindex notation – Värden kan nås med hjälp av index notation. PowerShell konverterar den notationen till ett anrop till objektparameteriserad egenskap för objektet.

    När du använder index notation med hashtables är värdet inom hakparenteserna nyckelnamnet. Om nyckeln är ett strängvärde omger du nyckelnamnet inom citattecken. Till exempel:

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

    I det här exemplet är nyckelvärdet 2 inte ett index i samlingen med värden. Det är värdet för nyckeln i nyckel/värde-paret. Du kan bevisa detta genom att indexera i samlingen med värden.

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

    När du använder index notation med ordlistor tolkas värdet inom hakparenteserna baserat på dess typ. Om värdet är ett heltal behandlas det som ett index i samlingen med värden. Om värdet inte är ett heltal behandlas det som nyckelnamnet. Till exempel:

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

    I det här exemplet är matrisvärdet [1] ett index i samlingen med värden med den parameteriserade egenskapsöverbelastningen Item(int index) . Matrisvärdet [[object]1] är inte ett index utan ett nyckelvärde med hjälp av överlagringen Item(System.Object key) .

    Kommentar

    Det här beteendet kan vara förvirrande när nyckelvärdet är ett heltal. När det är möjligt bör du undvika att använda heltalsnyckelvärden i ordlistor.

Hantera kollisioner med egenskapsnamn

Om nyckelnamnet kolliderar med ett av egenskapsnamnen HashTable av typen kan du använda den inbyggda psbase-medlemmen för att få åtkomst till dessa egenskaper. Om nyckelnamnet till exempel är keys och du vill returnera samlingen med nycklar använder du den här syntaxen HashTable :

$hashtable.psbase.Keys

Det här kravet gäller för andra typer som implementerar System.Collections.IDictionary gränssnittet, till exempel OrderedDictionary.

Iterera över nycklar och värden

Du kan iterera över nycklarna i en hashtable för att bearbeta värdena på flera sätt. Vart och ett av exemplen i det här avsnittet har identiska utdata. De itererar över variabeln $hash som definieras här:

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

Kommentar

I de här exemplen definieras $hash som en ordnad ordlista för att säkerställa att utdata alltid är i samma ordning. De här exemplen fungerar likadant för standard-hashtables, men utdataordningen är inte förutsägbar.

Varje exempel returnerar ett meddelande för varje nyckel och dess värde:

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

I det här exemplet används ett foreach block för att iterera över nycklarna.

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

Det här exemplet används ForEach-Object för att iterera över nycklarna.

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

I det GetEnumerator() här exemplet används metoden för att skicka varje nyckel/värde-par via pipelinen till ForEach-Object.

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

I det här exemplet används GetEnumerator() metoderna och ForEach() för att iterera över varje nyckel/värde-par.

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

Lägga till och ta bort nycklar och värden

När du skapar en hashtable inkluderar du vanligtvis nyckel/värde-paren i definitionen. Du kan dock lägga till och ta bort nyckel/värde-par från en hashtable när som helst. I följande exempel skapas en tom hashtable.

$hash = @{}

Du kan lägga till nyckel/värde-par med matris notation. I följande exempel läggs till exempel en Time nyckel med värdet Now för till hashtable.

$hash["Time"] = "Now"

Du kan också lägga till nycklar och värden i en hashtable med hjälp Add() av -metoden för System.Collections.Hashtable objektet. Metoden Add() har följande syntax:

Add(Key, Value)

Om du till exempel vill lägga till en Time nyckel med värdet Now i hashtableanvänder du följande instruktionsformat.

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

Och du kan lägga till nycklar och värden i en hashtable med additionsoperatorn (+) för att lägga till en hashtable i en befintlig hashtable. Följande instruktion lägger till exempel till en Time nyckel med värdet Now för hashtable i variabeln $hash .

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

Du kan också lägga till värden som lagras i variabler.

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

$hash.Add($t, $now)

Du kan inte använda en subtraktionsoperator för att ta bort ett nyckel/värde-par från en hash-tabell, men du kan använda Remove() -metoden för hashtable objektet. Metoden Remove har följande syntax:

$object.Remove(<key>)

I följande exempel tar du bort Time nyckel/värde-paret från $hash.

$hash.Remove("Time")

Objekttyper i HashTables

Nycklar och värden i en hashtable kan ha valfri .NET-objekttyp och en enda hashtable kan ha nycklar och värden av flera typer.

Följande instruktion skapar en hashtable av processnamnsträngar och processobjektvärden och sparar den i variabeln $p .

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

Du kan visa hashtable i $p och använda nyckelnamnsegenskaperna för att visa värdena.

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

Nycklarna i en hashtable kan vara valfri .NET-typ. Följande instruktion lägger till hashtable ett nyckel/värde-par i variabeln $p . Nyckeln är ett tjänstobjekt som representerar WinRM-tjänsten och värdet är tjänstens aktuella status.

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

Du kan visa och komma åt det nya nyckel/värde-paret med samma metoder som du använder för andra par i hashtable.

PS> $p

Name                           Value
----                           -----
PowerShell                     System.Diagnostics.Process (powershell)
Notepad                        System.Diagnostics.Process (Notepad)
WinRM                          Running

PS> $p.keys
PowerShell
Notepad

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

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

Nycklar och värden i en hashtable kan också vara Hashtable objekt. Följande instruktion lägger till hashtable nyckel/värde-par i variabeln $p där nyckeln är en sträng, Hash2, och värdet är ett hashtable med tre nyckel/värde-par.

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

Du kan visa och komma åt de nya värdena med samma metoder.

PS> $p

Name                           Value
----                           -----
PowerShell                     System.Diagnostics.Process (powershell)
Notepad                        System.Diagnostics.Process (Notepad)
WinRM                          Running
Hash2                          {c, b, a}

PS> $p.Hash2

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

PS> $p.Hash2.b
2

Sortera nycklar och värden

Objekten i en hashtable är i sig osorterade. Nyckel/värde-paren kan visas i en annan ordning varje gång du visar dem.

Även om du inte kan sortera en hashtablekan du använda GetEnumerator() metoden hashtables för att räkna upp nycklar och värden och sedan använda cmdleten Sort-Object för att sortera uppräknade värden för visning.

Följande kommandon räknar till exempel upp nycklar och värden i hash-tabellen i variabeln $p och sorterar sedan nycklarna i alfabetisk ordning.

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

Name                           Value
----                           -----
Hash2                          {c, b, a}
Notepad                        System.Diagnostics.Process (Notepad)
PowerShell                     System.Diagnostics.Process (powershell)
WinRM                          Running

Följande kommando använder samma procedur för att sortera hash-värdena i fallande ordning.

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

Name                           Value
----                           -----
PowerShell                     System.Diagnostics.Process (powershell)
Notepad                        System.Diagnostics.Process (Notepad)
Hash2                          {c, b, a}
WinRM                          Running

Skapa objekt från hashtables

Från och med PowerShell 3.0 kan du skapa ett objekt från en hashtable med egenskaper och egenskapsvärden.

Syntaxen ser ut så här:

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

Den här metoden fungerar endast för klasser som har en konstruktor som inte har några parametrar. Objektegenskaperna måste vara offentliga och kan ställas in.

Mer information finns i about_Object_Creation.

ConvertFrom-StringData

Cmdleten ConvertFrom-StringData konverterar en sträng eller en här-sträng med nyckel/värde-par till en hashtable. Du kan använda cmdleten ConvertFrom-StringData på ett säkert sätt i avsnittet Data i ett skript, och du kan använda den med cmdleten Import-LocalizedData för att visa användarmeddelanden i användargränssnittskulturen (UI) för den aktuella användaren.

Här-strängar är särskilt användbara när värdena i inkludera hashtable citattecken. Mer information om här-strängar finns i about_Quoting_Rules.

I följande exempel visas hur du skapar en här-sträng med användarmeddelandena i föregående exempel och hur du använder ConvertFrom-StringData för att konvertera dem från en sträng till en hashtable.

Följande kommando skapar en här-sträng av nyckel/värde-paren och sparar den sedan i variabeln $string .

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

Det här kommandot använder cmdleten ConvertFrom-StringData för att konvertera här-strängen till en hashtable.

ConvertFrom-StringData $string

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

Mer information om här-strängar finns i about_Quoting_Rules.

Se även