about_Hash_Tables
Krátký popis
Popisuje, jak vytvářet, používat a řadit hashovací tabulky v PowerShellu.
Dlouhý popis
Hashtable, označovaná také jako slovník nebo asociativní pole, je kompaktní datová struktura, která ukládá jeden nebo více párů klíč-hodnota. Například tabulka hash může obsahovat řadu IP adres a názvů počítačů, kde IP adresy jsou klíče a názvy počítačů jsou hodnoty nebo naopak.
V PowerShellu je každá zatřiďovací tabulka objektem [System.Collections.Hashtable]
. V PowerShellu můžete použít vlastnosti a metody Hashtable objektů.
Počínaje PowerShellem 3.0 můžete pomocí akcelerátoru [ordered]
typů vytvořit objekt v PowerShellu [System.Collections.Specialized.OrderedDictionary]
.
Seřazené slovníky se liší od hashovatelných tabulek v tom, že klíče se vždy zobrazují v pořadí, ve kterém je vypíšete. Pořadí klíčů v hashovatelné tabulce není deterministické.
Klíče a hodnota v hashtables jsou také objekty .NET. Nejčastěji se jedná o řetězce nebo celá čísla, ale můžou mít libovolný typ objektu. Můžete také vytvořit vnořené hashovací tabulky, ve kterých je hodnota klíče jinou hashovací tabulkou.
Hashtables se často používají, protože jsou efektivní pro hledání a načítání dat. K ukládání seznamů a vytváření počítaných vlastností v PowerShellu můžete použít hashovací tabulky. A rutina ConvertFrom-StringData
převede strukturovaná řetězcová data na hashtable.
Syntaxe
Syntaxe hashovatelné tabulky je následující:
@{ <name> = <value>; [<name> = <value> ] ...}
Syntaxe seřazeného slovníku je následující:
[ordered]@{ <name> = <value>; [<name> = <value> ] ...}
Akcelerátor [ordered]
typů byl zaveden v PowerShellu 3.0.
Pokud chcete vytvořit hashovací tabulku, postupujte podle těchto pokynů:
- Zahajte zatřiďovací tabulku znakem (
@
). - Uzavřete hashtable do složených závorek (
{}
). - Zadejte jeden nebo více párů klíč-hodnota pro obsah hashovatelné tabulky.
- K oddělení každého klíče od jeho hodnoty použijte znaménko rovná se (
=
). - K oddělení párů klíč-hodnota použijte středník (
;
) nebo konec řádku. - Klíče, které obsahují mezery, musí být uzavřeny v uvozovkách. Hodnoty musí být platné výrazy PowerShellu. Řetězce se musí zobrazovat v uvozovkách, i když neobsahují mezery.
- Pokud chcete spravovat zatřiďovací tabulku, uložte ji do proměnné.
- Při přiřazování uspořádané hashovatelné proměnné umístěte
[ordered]
typ před symbol@
. Pokud ji umístíte před název proměnné, příkaz selže.
Uspořádané slovníky můžete používat stejným způsobem jako hashovací tabulky. Typ lze použít jako hodnotu parametrů, které přebírají objekty typu hashtable nebo slovníku (iDictionary).
Vytváření hashovatelných tabulek a seřazených slovníků
Představte si následující příklady hashtable a seřazeného slovníku:
$hash = @{
1 = 'one'
2 = 'two'
'three' = 3
}
$hash
Name Value
---- -----
three 3
2 two
1 one
Jak vidíte, páry klíč-hodnota v hashovatelné tabulce se nezobrazují v pořadí, v jakém byly definovány.
Nejjednodušší způsob, jak vytvořit uspořádaný slovník, je použít [ordered]
atribut. Umístěte atribut bezprostředně před @
symbol.
$dictionary = [ordered]@{
1 = 'one'
2 = 'two'
'three' = 3
}
$dictionary
Name Value
---- -----
1 one
2 two
three 3
Na rozdíl odhashch
Převod hashovatelných tabulek a uspořádaných slovníků
Akcelerátor typů [ordered]
nemůžete použít k převodu nebo přetypování hashtable.
Pokud před název proměnné umístíte objednaný atribut, příkaz selže s následující chybovou zprávou.
[ordered]$orderedhash = @{}
ParserError:
Line |
1 | [ordered]$orderedhash = @{}
| ~~~~~~~~~~~~~~
| The ordered attribute can be specified only on a hash literal node.
Pokud chcete výraz opravit, přesuňte atribut [objednaný].
$orderedhash = [ordered]@{}
Uspořádaný slovník můžete přetypovat na hashtable, ale nemůžete zaručit pořadí členů.
[hashtable]$newhash = [ordered]@{
Number = 1
Shape = "Square"
Color = "Blue"
}
$newhash
Name Value
---- -----
Color Blue
Shape Square
Number 1
Hashtable a vlastnosti slovníku
Hashtables and ordered dictionaries share několik vlastností. Vezměte v úvahu proměnné $hash
$dictionary
definované v předchozích příkladech.
$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;}
Nejčastěji používané vlastnosti jsou Počet, Klíče, Hodnoty a Položka.
Count vlastnost, která označuje počet párů klíč-hodnota v objektu.
Vlastnost Klíče je kolekce názvů klíčů v hashtable nebo slovníku.
PS> $hash.Keys three 2 1 PS> $dictionary.Keys 1 2 three
Vlastnost Values je kolekce hodnot v hashtable nebo slovníku.
PS> $hash.Values 3 two one PS> $dictionary.Values one two 3
Vlastnost Item je parametrizovaná vlastnost, která vrací hodnotu položky, kterou zadáte. Hashtables používají klíč jako parametr parametrizované vlastnosti, zatímco slovníky používají index ve výchozím nastavení. Tento rozdíl má vliv na přístup k hodnotám pro každý typ.
Přístup k hodnotám
Existují dva běžné způsoby přístupu k hodnotám v hashtable nebo slovníku: zápis člena nebo index pole.
Zápis člena – K hodnotám lze přistupovat pomocí názvu klíče jako vlastnosti člena objektu. Příklad:
PS> $hash.1 one PS> $dictionary.2 two
Zápis indexu pole – k hodnotám lze přistupovat pomocí zápisu indexu. PowerShell převede zápis na volání item parametrizované vlastnosti objektu.
Pokud používáte zápis indexu s hashtables, hodnota uvnitř závorek je název klíče. Pokud je klíč řetězcovou hodnotou, uzavřete název klíče do uvozovek. Příklad:
PS> $hash['three'] 3 PS> $hash[2] two
V tomto příkladu není hodnota
2
klíče indexem do kolekce hodnot. Jedná se o hodnotu klíče v páru klíč-hodnota. Můžete to prokázat indexováním do kolekce hodnot.PS> ([array]$hash.Values)[2] one
Při použití zápisu indexu se slovníky, hodnota uvnitř závorek se interpretuje na základě jeho typu. Pokud je hodnota celé číslo, považuje se za index do kolekce hodnot. Pokud hodnota není celé číslo, považuje se za název klíče. Příklad:
PS> $dictionary[1] two PS> ([array]$dictionary.Values)[1] two PS> $dictionary[[object]1] one PS> $dictionary['three'] 3
V tomto příkladu je maticová hodnota
[1]
indexem do kolekce hodnot pomocíItem(int index)
parametrizovaného přetížení vlastnosti. Hodnota[[object]1]
pole není index, ale hodnota klíče využívajícíItem(System.Object key)
přetížení.Poznámka:
Toto chování může být matoucí, pokud je hodnota klíče celé číslo. Pokud je to možné, neměli byste ve slovníkech používat celočíselné hodnoty klíče.
Zpracování kolizí názvů vlastností
Pokud název klíče koliduje s jedním z názvů vlastností typu HashTable, můžete pro přístup k těmto vlastnostem použít psbasevnitřní člen. Pokud je například název klíče keys
a chcete vrátit kolekci klíčů HashTable, použijte tuto syntaxi:
$hashtable.psbase.Keys
Tento požadavek platí pro jiné typy, které implementují System.Collections.IDictionary rozhraní, například OrderedDictionary.
Iterace nad klíči a hodnotami
Klíče v hashovatelné tabulce můžete iterovat, abyste hodnoty zpracovávala několika způsoby. Každý z příkladů v této části má stejný výstup. Iterují proměnnou definovanou $hash
zde:
$hash = [ordered]@{Number = 1; Shape = "Square"; Color = "Blue"}
Poznámka:
V těchto příkladech je definován jako seřazený slovník, aby se zajistilo, $hash
že výstup bude vždy ve stejném pořadí. Tyto příklady fungují stejně pro standardní hashtables, ale pořadí výstupu není předvídatelné.
Každý příklad vrátí zprávu pro každý klíč a jeho hodnotu:
The value of 'Number' is: 1
The value of 'Shape' is: Square
The value of 'Color' is: Blue
V tomto příkladu foreach
se k iteraci klíčů používá blok.
foreach ($Key in $hash.Keys) {
"The value of '$Key' is: $($hash[$Key])"
}
Tento příklad se používá ForEach-Object
k iteraci klíčů.
$hash.Keys | ForEach-Object {
"The value of '$_' is: $($hash[$_])"
}
Tento příklad používá metodu GetEnumerator()
k odeslání každého páru klíč-hodnota prostřednictvím kanálu do ForEach-Object
.
$hash.GetEnumerator() | ForEach-Object {
"The value of '$($_.Key)' is: $($_.Value)"
}
V tomto příkladu GetEnumerator()
se používají metody a ForEach()
iterace nad jednotlivými páry klíč-hodnota.
$hash.GetEnumerator().ForEach({"The value of '$($_.Key)' is: $($_.Value)"})
Přidávání a odebírání klíčů a hodnot
Při vytváření hashovací tabulky obvykle zahrnete páry klíč-hodnota do definice. Páry klíč-hodnota ale můžete kdykoli přidat a odebrat z hashovací tabulky. Následující příklad vytvoří prázdnou hashtable.
$hash = @{}
Páry klíč-hodnota můžete přidat pomocí zápisu pole. Následující příklad například přidá klíč Time
s hodnotou Now
do hashtable.
$hash["Time"] = "Now"
K hashtable můžete také přidat klíče a hodnoty pomocí Add()
metody System.Collections.Hashtable objektu. Metoda Add()
má následující syntaxi:
Add(Key, Value)
Pokud chcete například přidat klíč Time
s hodnotou Now
do hashtable, použijte následující formát příkazu.
$hash.Add("Time", "Now")
A můžete přidat klíče a hodnoty do hashtable pomocí operátoru sčítání (+
) a přidat hashtable do existující hashtable. Následující příkaz například přidá klíč Time
s hodnotou Now
do hashtable v proměnné $hash
.
$hash = $hash + @{Time="Now"}
Můžete také přidat hodnoty uložené v proměnných.
$t = "Today"
$now = (Get-Date)
$hash.Add($t, $now)
Operátor odčítání nelze použít k odebrání páru klíč-hodnota z tabulky hash, ale můžete použít Remove()
metodu hashtable objektu. Metoda Remove
má následující syntaxi:
$object.Remove(<key>)
Následující příklad odebere dvojici Time
klíč-hodnota z $hash
.
$hash.Remove("Time")
Typy objektů v tabulkách hash
Klíče a hodnoty v hashtable můžou mít libovolný typ objektu .NET a jedna hashtable může obsahovat klíče a hodnoty více typů.
Následující příkaz vytvoří hashovatelné řetězce názvů procesů a hodnoty procesních objektů a uloží ho do proměnné $p
.
$p = @{
"PowerShell" = (Get-Process PowerShell)
"Notepad" = (Get-Process notepad)
}
V $p
můžete zobrazit hashovací tabulku a pomocí vlastností názvu klíče zobrazit hodnoty.
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
Klíče v hashovatelné tabulce můžou být libovolný typ .NET. Následující příkaz přidá pár klíč-hodnota do hashtable v proměnné $p
. Klíč je objekt služby , který představuje službu WinRM a hodnota je aktuální stav služby.
$p = $p + @{
(Get-Service WinRM) = ((Get-Service WinRM).Status)
}
Nový pár klíč-hodnota můžete zobrazit a získat k němu přístup pomocí stejných metod, které používáte pro jiné páry v hashtable.
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
Klíče a hodnoty v hashovatelné tabulce mohou být také Hashtable objekty. Následující příkaz přidá pár klíč-hodnota do hashtable v proměnné $p
, ve které je klíč řetězec, Hash2 a hodnota je hashtable se třemi páry klíč-hodnota.
$p = $p + @{
"Hash2"= @{a=1; b=2; c=3}
}
K novým hodnotám můžete přistupovat stejnými metodami.
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
Řazení klíčů a hodnot
Položky v hashtable jsou vnitřně neuspořádané. Páry klíč-hodnota se můžou zobrazovat v jiném pořadí pokaždé, když je zobrazíte.
I když nemůžete řadit hashtable, můžete použít GetEnumerator()
metodu hashtables k vytvoření výčtu klíčů a hodnot a potom pomocí rutiny Sort-Object
seřadit výčtové hodnoty pro zobrazení.
Například následující příkazy vyčíslí klíče a hodnoty v tabulce hash v $p
proměnné a potom seřadí klíče v abecedním pořadí.
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
Následující příkaz používá stejný postup k seřazení hodnot hash v sestupném pořadí.
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
Vytváření objektů z hashtables
Počínaje PowerShellem 3.0 můžete vytvořit objekt z hashtable vlastností a hodnot vlastností.
Syntaxe je následující:
[<class-name>]@{
<property-name>=<property-value>
<property-name>=<property-value>
}
Tato metoda funguje pouze pro třídy, které mají konstruktor, který nemá žádné parametry. Vlastnosti objektu musí být veřejné a nastavené.
Další informace najdete v tématu about_Object_Creation.
ConvertFrom-StringData
Rutina ConvertFrom-StringData
převede řetězec nebo here-řetězec párů klíč-hodnota na hashtable. Rutinu ConvertFrom-StringData
můžete bezpečně použít v části Data skriptu a pomocí této Import-LocalizedData
rutiny můžete zobrazit uživatelské zprávy v jazykové verzi uživatelského rozhraní aktuálního uživatele.
Tady jsou řetězce zvlášť užitečné, když hodnoty v hashtable obsahují uvozovky. Další informace o tomto řetězci najdete v tématu about_Quoting_Rules.
Následující příklad ukazuje, jak vytvořit zde řetězec zpráv uživatele v předchozím příkladu a jak použít ConvertFrom-StringData
k převodu z řetězce na hashtable.
Následující příkaz vytvoří zde řetězec párů klíč-hodnota a pak ho uloží do $string
proměnné.
$string = @"
Msg1 = Type "Windows".
Msg2 = She said, "Hello, World."
Msg3 = Enter an alias (or "nickname").
"@
Tento příkaz používá rutinu ConvertFrom-StringData
k převodu tohoto řetězce na hashtable.
ConvertFrom-StringData $string
Name Value
---- -----
Msg3 Enter an alias (or "nickname").
Msg2 She said, "Hello, World."
Msg1 Type "Windows".
Další informace o tomto řetězci najdete v tématu about_Quoting_Rules.