about_Hash_Tables
Korte beschrijving
Hierin wordt beschreven hoe u hashtabellen maakt, gebruikt en sorteert in PowerShell.
Lange beschrijving
Een hashtable, 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 elk hashtable 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 hashtable 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, waarin de waarde van een sleutel een andere hashtableis.
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 hashtable.
Syntaxis
De syntaxis van een hashtable 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 hashtablete maken:
- hashtable Begin met een bijteken (
@
). - Plaats de hashtable accolades (
{}
). - Voer een of meer sleutel-waardeparen in voor de inhoud van de hashtable.
- 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 variabele wilt beheren, slaat u deze hashtableop in een variabele.
- Wanneer u een geordende variabele hashtable toewijst, 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. Beide typen kunnen worden gebruikt als de waarde van parameters die een hashtable of woordenlijstobjecteniDictionary () gebruiken.
Hashtables en geordende woordenlijsten maken
Bekijk de volgende hashtable en geordende woordenlijstvoorbeelden:
$hash = @{
1 = 'one'
2 = 'two'
'three' = 3
}
$hash
Name Value
---- -----
three 3
2 two
1 one
Zoals u kunt zien, worden de sleutel-waardeparen in een hashtable 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.
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 casten naar een hashtable, 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 Sleutels is een verzameling sleutelnamen in de hashtable of woordenlijst.
PS> $hash.Keys three 2 1 PS> $dictionary.Keys 1 2 three
De eigenschap Waarden is een verzameling van de waarden in de hashtable 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 hashtable 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] 2
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 HashTable type, kunt u het intrinsieke psbase-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 hashtable op verschillende manieren herhalen om de waarden 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 hashtable sleutel-waardeparen maakt in de definitie, neemt u meestal de sleutel-waardeparen op. U kunt echter op elk gewenst moment sleutel-waardeparen toevoegen aan en verwijderen.hashtable In het volgende voorbeeld wordt een lege hashtable.
$hash = @{}
U kunt sleutel-waardeparen toevoegen met behulp van matrix-notatie. In het volgende voorbeeld wordt bijvoorbeeld een Time
sleutel met een waarde aan Now
de hashtablesleutel toegevoegd.
$hash["Time"] = "Now"
U kunt ook sleutels en waarden toevoegen aan een hashtable 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 met een waarde aan Now
de hashtablesleutel wilt toevoegen, gebruikt u de volgende instructieindeling.
$hash.Add("Time", "Now")
En u kunt sleutels en waarden toevoegen aan een hashtable met behulp van de optellingsoperator (+
) om een hashtable aan een bestaande hashtabletoe te voegen. Met de volgende instructie wordt bijvoorbeeld een Time
sleutel met een waarde aan Now
de hashtable $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 hashtable object 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 hashtable kunnen elk .NET-objecttype hebben en één hashtable kan sleutels en waarden van meerdere typen bevatten.
Met de volgende instructie maakt u een hashtable reeks tekenreeksen voor procesnamen en objectwaarden en slaat u deze op in de $p
variabele.
$p = @{
"PowerShell" = (Get-Process PowerShell)
"Notepad" = (Get-Process notepad)
}
U kunt de eigenschappen $p
van de hashtable sleutelnaam weergeven en 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 hashtable kunnen elk .NET-type zijn. Met de volgende instructie wordt een sleutel-waardepaar aan de hashtable $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 gebruikt voor andere paren in de 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
De sleutels en waarden in een hashtable kunnen ook objecten zijn Hashtable . De volgende instructie voegt sleutel-waardepaar toe aan de hashtable $p
variabele waarin de sleutel een tekenreeks, Hash2 en de waarde een hashtable met drie sleutel-waardeparen is.
$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 (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
Sleutels en waarden sorteren
De items in een hashtable zijn intrinsiek ongeordeerd. De sleutel-waardeparen worden mogelijk in een andere volgorde weergegeven telkens wanneer u ze weergeeft.
Hoewel u een hashtableniet kunt sorteren, kunt u de GetEnumerator()
methode van hashtables gebruiken om de sleutels en waarden op te sommen en vervolgens de Sort-Object
cmdlet 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 {c, b, a}
Notepad System.Diagnostics.Process (Notepad)
PowerShell System.Diagnostics.Process (powershell)
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 (powershell)
Notepad System.Diagnostics.Process (Notepad)
Hash2 {c, b, a}
WinRM Running
Objecten maken op afstand van hashtabellen
Vanaf PowerShell 3.0 kunt u een object maken op basis van eigenschappen hashtable 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 ConvertFrom-StringData
cmdlet converteert een tekenreeks of een here-tekenreeks van sleutel-waardeparen naar een hashtable. 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 hashtable aanhalingstekens tussen aanhalingstekens staan. 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 deze kunt converteren ConvertFrom-StringData
van een tekenreeks naar een hashtable.
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 ConvertFrom-StringData
cmdlet gebruikt om de here-string te converteren naar een hashtable.
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.