Dela via


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 varje hashtable ett [System.Collections.Hashtable] objekt. 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:

  • Börja hashtabellen med ett vidtecken (@).
  • Omslut hashtabellen i klammerparenteser ({}).
  • Ange ett eller flera nyckel/värde-par för innehållet i hash-tabellen.
  • 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 hashtabellen sparar du den i en variabel.
  • När du tilldelar en ordnad hashtabell 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 en hashtable- eller ordlista (iDictionary) typobjekt.

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 som 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] typaccelerator 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 medlemmarnas ordning.

[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 nyckelnamn i hashtable- eller ordlistan.

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

    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 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]
    two
    

    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 för HashTable typ kan du använda psbaseinbyggd medlem för att få åtkomst till dessa egenskaper. Om nyckelnamnet till exempel är keys och du vill returnera samlingen av HashTable- nycklar använder du den här syntaxen:

$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 hash-tabell.

$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 till hashtabellen.

$hash["Time"] = "Now"

Du kan också lägga till nycklar och värden i en hashtable med hjälp av Add()-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 till hashtabellen använder du följande instruktionsformat.

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

Och du kan lägga till nycklar och värden i en hashtable med hjälp av 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 till hashtabellen 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 metoden Remove() 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 hashtabell med processnamnsträngar och processobjektvärden och sparar den i variabeln $p.

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

Du kan visa hashtabellen 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 ett nyckel/värde-par i hashtabellen 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 hashtabellen.

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

Nycklar och värden i en hashtable kan också vara Hashtable objekt. Följande instruktion lägger till nyckel/värde-par i hashtabellen i $p variabeln där nyckeln är en sträng, Hash2, och värdet är en 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 (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

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 hashtable kan du använda metoden GetEnumerator() 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                          {[a, 1], [b, 2], [c, 3]}
Notepad                        System.Diagnostics.Process (Notepad)
PowerShell                     System.Diagnostics.Process (pwsh)
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 (pwsh)
Notepad                        System.Diagnostics.Process (Notepad)
Hash2                          {[a, 1], [b, 2], [c, 3]}
WinRM                          Running

Skapa objekt från hashtables

Från och med PowerShell 3.0 kan du skapa ett objekt från en hashtabell 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 hashtabellen innehåller 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