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överbelastningenItem(int index)
. Matrisvärdet[[object]1]
är inte ett index utan ett nyckelvärde med hjälp av överlagringenItem(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.