about_Hash_Tables
Korte beschrijving
Hierin wordt beschreven hoe u hashtabellen maakt, gebruikt en sorteert in PowerShell.
Lange beschrijving
Een hashtabel, ook wel een woordenlijst of associatieve matrix genoemd, is een compacte gegevensstructuur waarin een of meer sleutel-waardeparen worden opgeslagen. Een hashtabel kan bijvoorbeeld een reeks IP-adressen en computernamen bevatten, waarbij de IP-adressen de sleutels zijn en de computernamen de waarden zijn, of omgekeerd.
In PowerShell is elke hashtabel een [System.Collections.Hashtable]
-object. U kunt de eigenschappen en methoden van Hashtable objecten in PowerShell gebruiken.
Vanaf PowerShell 3.0 kunt u de [ordered]
typeversneller gebruiken om een [System.Collections.Specialized.OrderedDictionary]
object te maken in PowerShell.
Geordende woordenlijsten verschillen van hashtabellen omdat de sleutels altijd worden weergegeven in de volgorde waarin u ze opgeeft. De volgorde van sleutels in een hashtabel is niet deterministisch.
De sleutels en waarde in hashtabellen zijn ook .NET-objecten. Dit zijn meestal tekenreeksen of gehele getallen, maar ze kunnen elk objecttype hebben. U kunt ook geneste hashtabellen maken, waarbij de waarde van een sleutel een andere hashtabel is.
Hashtables worden vaak gebruikt omdat ze efficiënt zijn voor het zoeken en ophalen van gegevens. U kunt hashtabellen gebruiken om lijsten op te slaan en berekende eigenschappen te maken in PowerShell. En met de ConvertFrom-StringData
-cmdlet worden gestructureerde tekenreeksgegevens geconverteerd naar een hashtabel.
Syntaxis
De syntaxis van een hashtabel is als volgt:
@{ <name> = <value>; [<name> = <value> ] ...}
De syntaxis van een geordende woordenlijst is als volgt:
[ordered]@{ <name> = <value>; [<name> = <value> ] ...}
De [ordered]
typeversneller is geïntroduceerd in PowerShell 3.0.
Volg deze richtlijnen om een hashtabel te maken:
- Begin de hashtabel met een aanteken (
@
). - Plaats de hashtabel tussen accolades (
{}
). - Voer een of meer sleutel-waardeparen in voor de inhoud van de hashtabel.
- Gebruik een gelijkteken (
=
) om elke sleutel te scheiden van de waarde. - Gebruik een puntkomma (
;
) of een regeleinde om de sleutel-waardeparen te scheiden. - Sleutels die spaties bevatten, moeten tussen aanhalingstekens worden geplaatst. Waarden moeten geldige PowerShell-expressies zijn. Tekenreeksen moeten tussen aanhalingstekens worden weergegeven, zelfs als ze geen spaties bevatten.
- Als u de hashtabel wilt beheren, slaat u deze op in een variabele.
- Wanneer u een geordende hashtabel toewijst aan een variabele, plaatst u het
[ordered]
type vóór het@
symbool. Als u deze vóór de naam van de variabele plaatst, mislukt de opdracht.
U kunt geordende woordenlijsten op dezelfde manier gebruiken als u hashtables gebruikt. Ieder type kan worden gebruikt als waarde van parameters die hashtabel- of woordenlijsttype objecten verwachten (iDictionary).
Hashtables en geordende woordenlijsten maken
Bekijk de volgende hashtabel- en geordende woordenlijstvoorbeelden:
$hash = @{
1 = 'one'
2 = 'two'
'three' = 3
}
$hash
Name Value
---- -----
three 3
2 two
1 one
Zoals u ziet, worden de sleutel-waardeparen in een hashtabel niet weergegeven in de volgorde waarin ze zijn gedefinieerd.
De eenvoudigste manier om een geordende woordenlijst te maken, is door het [ordered]
kenmerk te gebruiken. Plaats het kenmerk direct vóór het @
symbool.
$dictionary = [ordered]@{
1 = 'one'
2 = 'two'
'three' = 3
}
$dictionary
Name Value
---- -----
1 one
2 two
three 3
In tegenstelling tot hashtables behouden geordende woordenlijsten de volgorde van de sleutelwaarde.
Hashtables en geordende woordenlijsten converteren
U kunt de [ordered]
typeversneller niet gebruiken om een hashtable te converteren of te casten.
Als u het geordende kenmerk vóór de naam van de variabele plaatst, mislukt de opdracht met het volgende foutbericht.
[ordered]$orderedhash = @{}
ParserError:
Line |
1 | [ordered]$orderedhash = @{}
| ~~~~~~~~~~~~~~
| The ordered attribute can be specified only on a hash literal node.
Als u de expressie wilt corrigeren, verplaatst u het kenmerk [geordende] .
$orderedhash = [ordered]@{}
U kunt een geordende woordenlijst naar een hashtabel casten, maar u kunt de volgorde van de leden niet garanderen.
[hashtable]$newhash = [ordered]@{
Number = 1
Shape = "Square"
Color = "Blue"
}
$newhash
Name Value
---- -----
Color Blue
Shape Square
Number 1
Hashtable en woordenlijsteigenschappen
Hashtables en geordende woordenlijsten delen verschillende eigenschappen. Houd rekening met de $hash
variabelen die $dictionary
zijn gedefinieerd in de vorige voorbeelden.
$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 meest gebruikte eigenschappen zijn Count, Keys, Values en Item.
De eigenschap Count die het aantal sleutel-waardeparen in het object aangeeft.
De eigenschap Keys is een verzameling sleutelnamen in de hashtabel of woordenlijst.
PS> $hash.Keys three 2 1 PS> $dictionary.Keys 1 2 three
De eigenschap Waarden is een verzameling waarden in de hashtabel of woordenlijst.
PS> $hash.Values 3 two one PS> $dictionary.Values one two 3
De eigenschap Item is een geparameteriseerde eigenschap die de waarde retourneert van het item dat u opgeeft. Hashtables gebruiken de sleutel als parameter voor de geparameteriseerde eigenschap, terwijl woordenlijsten de index standaard gebruiken. Dit verschil is van invloed op de manier waarop u toegang krijgt tot de waarden voor elk type.
Toegang tot waarden
Er zijn twee veelvoorkomende manieren om toegang te krijgen tot de waarden in een hashtabel of woordenlijst: notatie van leden of matrixindex notatie.
Lid-notatie : waarden kunnen worden geopend met behulp van de sleutelnaam als lideigenschap van het object. Voorbeeld:
PS> $hash.1 one PS> $dictionary.2 two
Matrixindex notatie : waarden kunnen worden geopend met behulp van index notatie. PowerShell converteert die notatie naar een aanroep naar de eigenschap Itemparameter van het object.
Wanneer u index notatie met hashtables gebruikt, is de waarde binnen de vierkante haken de sleutelnaam. Als de sleutel een tekenreekswaarde is, plaatst u de sleutelnaam tussen aanhalingstekens. Voorbeeld:
PS> $hash['three'] 3 PS> $hash[2] two
In dit voorbeeld is de sleutelwaarde
2
geen index in de verzameling waarden. Dit is de waarde van de sleutel in het sleutel-waardepaar. U kunt dit bewijzen door te indexeren in de verzameling waarden.PS> ([array]$hash.Values)[2] one
Wanneer u index notatie met woordenlijsten gebruikt, wordt de waarde binnen de vierkante haken geïnterpreteerd op basis van het type. Als de waarde een geheel getal is, wordt deze beschouwd als een index in de verzameling waarden. Als de waarde geen geheel getal is, wordt deze behandeld als de sleutelnaam. Voorbeeld:
PS> $dictionary[1] two PS> ([array]$dictionary.Values)[1] two PS> $dictionary[[object]1] one PS> $dictionary['three'] 3
In dit voorbeeld is de matrixwaarde
[1]
een index in de verzameling waarden met behulp van deItem(int index)
overbelaste eigenschap met parameters. De matrixwaarde[[object]1]
is geen index, maar een sleutelwaarde die gebruikmaakt van deItem(System.Object key)
overbelasting.Notitie
Dit gedrag kan verwarrend zijn wanneer de sleutelwaarde een geheel getal is. Indien mogelijk moet u het gebruik van sleutelwaarden voor gehele getallen in woordenlijsten vermijden.
Conflicten tussen eigenschapsnamen afhandelen
Als de sleutelnaam conflicteert met een van de eigenschapsnamen van het type HashTable, kunt u de psbaseintrinsiek lid gebruiken om toegang te krijgen tot deze eigenschappen. Als de sleutelnaam bijvoorbeeld is keys
en u de verzameling van de HashTable--sleutels wilt retourneren, gebruikt u deze syntaxis:
$hashtable.psbase.Keys
Deze vereiste is van toepassing op andere typen die de System.Collections.IDictionary interface implementeren, zoals OrderedDictionary.
Herhalen van sleutels en waarden
U kunt de sleutels in een hashtabel herhalen om de waarden op verschillende manieren te verwerken. Elk van de voorbeelden in deze sectie heeft identieke uitvoer. Ze herhalen de $hash
variabele die hier is gedefinieerd:
$hash = [ordered]@{Number = 1; Shape = "Square"; Color = "Blue"}
Notitie
In deze voorbeelden $hash
wordt gedefinieerd als een geordende woordenlijst om ervoor te zorgen dat de uitvoer altijd in dezelfde volgorde staat. Deze voorbeelden werken hetzelfde voor standaard-hashtabellen, maar de volgorde van de uitvoer is niet voorspelbaar.
Elk voorbeeld retourneert een bericht voor elke sleutel en de bijbehorende waarde:
The value of 'Number' is: 1
The value of 'Shape' is: Square
The value of 'Color' is: Blue
In dit voorbeeld wordt een foreach
blok gebruikt om de sleutels te herhalen.
foreach ($Key in $hash.Keys) {
"The value of '$Key' is: $($hash[$Key])"
}
In dit voorbeeld wordt gebruikgemaakt ForEach-Object
van het herhalen van de sleutels.
$hash.Keys | ForEach-Object {
"The value of '$_' is: $($hash[$_])"
}
In dit voorbeeld wordt de GetEnumerator()
methode gebruikt om elk sleutel-waardepaar via de pijplijn naar ForEach-Object
te verzenden.
$hash.GetEnumerator() | ForEach-Object {
"The value of '$($_.Key)' is: $($_.Value)"
}
In dit voorbeeld worden de GetEnumerator()
en ForEach()
methoden gebruikt om elk sleutel-waardepaar te herhalen.
$hash.GetEnumerator().ForEach({"The value of '$($_.Key)' is: $($_.Value)"})
Sleutels en waarden toevoegen en verwijderen
Wanneer u een hashtabel maakt, neemt u doorgaans de sleutel-waardeparen op in de definitie. U kunt echter op elk gewenst moment sleutel-waardeparen toevoegen aan en verwijderen uit een hashtabel. In het volgende voorbeeld wordt een lege hashtabel gemaakt.
$hash = @{}
U kunt sleutel-waardeparen toevoegen met behulp van matrix-notatie. In het volgende voorbeeld wordt bijvoorbeeld een Time
sleutel met een waarde van Now
aan de hashtabel toegevoegd.
$hash["Time"] = "Now"
U kunt ook sleutels en waarden toevoegen aan een hashtabel met behulp van de Add()
methode van het System.Collections.Hashtable-object. De Add()
methode heeft de volgende syntaxis:
Add(Key, Value)
Als u bijvoorbeeld een Time
sleutel wilt toevoegen met een waarde van Now
aan de hashtabel, gebruikt u de volgende instructieindeling.
$hash.Add("Time", "Now")
En u kunt sleutels en waarden toevoegen aan een hashtabel met behulp van de optellingsoperator (+
) waarmee u een hashtabel toevoegt aan een bestaande hashtabel. Met de volgende instructie wordt bijvoorbeeld een Time
sleutel met een waarde van Now
aan de hashtabel in de $hash
variabele toegevoegd.
$hash = $hash + @{Time="Now"}
U kunt ook waarden toevoegen die zijn opgeslagen in variabelen.
$t = "Today"
$now = (Get-Date)
$hash.Add($t, $now)
U kunt geen aftrekkingsoperator gebruiken om een sleutel-waardepaar uit een hash-tabel te verwijderen, maar u kunt de Remove()
methode van het hashtabelobject gebruiken. De Remove
methode heeft de volgende syntaxis:
$object.Remove(<key>)
In het volgende voorbeeld wordt het Time
sleutel-waardepaar verwijderd uit $hash
.
$hash.Remove("Time")
Objecttypen in HashTables
De sleutels en waarden in een hashtabel kunnen elk .NET-objecttype hebben en één hashtabel kan sleutels en waarden van meerdere typen bevatten.
Met de volgende instructie maakt u een hashtabel met procesnaamtekenreeksen en objectwaarden voor processen en slaat u deze op in de $p
variabele.
$p = @{
"PowerShell" = (Get-Process PowerShell)
"Notepad" = (Get-Process notepad)
}
U kunt de hashtabel in $p
weergeven en de sleutelnaameigenschappen gebruiken om de waarden weer te geven.
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
De sleutels in een hashtabel kunnen elk .NET-type zijn. Met de volgende instructie wordt een sleutel-waardepaar aan de hashtabel in de $p
variabele toegevoegd. De sleutel is een serviceobject dat de WinRM-service vertegenwoordigt en de waarde de huidige status van de service is.
$p = $p + @{
(Get-Service WinRM) = ((Get-Service WinRM).Status)
}
U kunt het nieuwe sleutel-waardepaar weergeven en openen met dezelfde methoden die u voor andere paren in de hashtabel gebruikt.
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
De sleutels en waarden in een hashtabel kunnen ook Hashtable objecten zijn. De volgende instructie voegt sleutel-waardepaar toe aan de hashtabel in de $p
variabele waarin de sleutel een tekenreeks, Hash2 en de waarde een hashtabel is met drie sleutel-waardeparen.
$p = $p + @{
"Hash2"= @{a=1; b=2; c=3}
}
U kunt de nieuwe waarden weergeven en openen met dezelfde methoden.
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
Sleutels en waarden sorteren
De items in een hashtabel zijn intrinsiek ongeordeerd. De sleutel-waardeparen worden mogelijk in een andere volgorde weergegeven telkens wanneer u ze weergeeft.
Hoewel u een hashtabel niet kunt sorteren, kunt u de GetEnumerator()
methode van hashtabellen gebruiken om de sleutels en waarden op te sommen en vervolgens de cmdlet Sort-Object
gebruiken om de geïnventareerde waarden voor weergave te sorteren.
Met de volgende opdrachten worden bijvoorbeeld de sleutels en waarden in de hash-tabel in de $p
variabele opgesomd en worden de sleutels vervolgens in alfabetische volgorde gesorteerd.
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
De volgende opdracht gebruikt dezelfde procedure om de hashwaarden in aflopende volgorde te sorteren.
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
Objecten maken op afstand van hashtabellen
Vanaf PowerShell 3.0 kunt u een object maken op basis van een hashtabel met eigenschappen en eigenschapswaarden.
De syntaxis is als volgt:
[<class-name>]@{
<property-name>=<property-value>
<property-name>=<property-value>
}
Deze methode werkt alleen voor klassen die een constructor hebben die geen parameters heeft. De objecteigenschappen moeten openbaar en ingesteld zijn.
Zie about_Object_Creation voor meer informatie.
ConvertFrom-StringData
De cmdlet ConvertFrom-StringData
converteert een tekenreeks of een here-tekenreeks van sleutel-waardeparen naar een hashtabel. U kunt de ConvertFrom-StringData
cmdlet veilig gebruiken in de sectie Gegevens van een script en u kunt deze gebruiken met de Import-LocalizedData
cmdlet om gebruikersberichten weer te geven in de gebruikersinterfacecultuur van de huidige gebruiker.
Hier zijn tekenreeksen vooral handig wanneer de waarden in de hashtabel aanhalingstekens bevatten. Zie about_Quoting_Rules voor meer informatie over deze tekenreeksen.
In het volgende voorbeeld ziet u hoe u een hier-tekenreeks maakt van de gebruikersberichten in het vorige voorbeeld en hoe u ConvertFrom-StringData
gebruikt om deze te converteren van een tekenreeks naar een hashtabel.
Met de volgende opdracht maakt u een here-string van de sleutel-waardeparen en slaat u deze vervolgens op in de $string
variabele.
$string = @"
Msg1 = Type "Windows".
Msg2 = She said, "Hello, World."
Msg3 = Enter an alias (or "nickname").
"@
Met deze opdracht wordt de cmdlet ConvertFrom-StringData
gebruikt om de hier-tekenreeks te converteren naar een hashtabel.
ConvertFrom-StringData $string
Name Value
---- -----
Msg3 Enter an alias (or "nickname").
Msg2 She said, "Hello, World."
Msg1 Type "Windows".
Zie about_Quoting_Rules voor meer informatie over deze tekenreeksen.