Sdílet prostřednictvím


O_Hašovacích_tabulkách

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 hashtable 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 typů [ordered] vytvořit objekt [System.Collections.Specialized.OrderedDictionary] v PowerShellu.

Uspořádané slovníky se liší od hešovacích tabulek v tom, že klíče se vždy zobrazují v pořadí, ve kterém je zadáte. 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 typů [ordered] 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 hašovací tabulku do složených závorek ({}).
  • Zadejte jeden nebo více párů klíč-hodnota pro obsah hashovatelné tabulky.
  • Znaménko rovnosti (=) slouží k oddělení každého klíče od jeho hodnoty.
  • 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 v PowerShellu. Řetězce se musí zobrazovat v uvozovkách, i když neobsahují mezery.
  • Pro správu hešovací tabulky ji uložte do proměnné.
  • Při přiřazování uspořádané hashové tabulky do proměnné umístěte typ [ordered] 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. Oba typy lze použít jako hodnotu parametrů, které přijímají objekty typu hashtable nebo slovník (iDictionary).

Vytváření hashovatelných tabulek a seřazených slovníků

Zvažte následující příklady hašovací tabulky a uspořádané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 atribut [ordered]. 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 od hashtabulí, uspořádané slovníky zachovávají pořadí klíč-hodnota.

Převod hashovatelných tabulek a uspořádaných slovníků

Typový akcelerátor [ordered] nelze použít k převodu nebo přetypování tabulky hash. 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 [seřazený].

$orderedHash = [ordered]@{}

Uspořádaný slovník můžete přetypovat na hašovací tabulku, ale nemůžete zaručit pořadí prvků.

[hashtable]$newHash = [ordered]@{
    Number = 1
    Shape = "Square"
    Color = "Blue"
}
$newHash
Name                           Value
----                           -----
Color                          Blue
Shape                          Square
Number                         1

Hashtable a vlastnosti slovníku

Tabulky hash a uspořádané slovníky sdílejí několik vlastností. Zvažte $hash a $dictionary proměnné 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, hodnotya položky.

  • Vlastnost Count, která označuje počet dvojic klíč-hodnota v objektu.

  • Vlastnost Klíče je kolekce klíčových názvů v hašovací tabulce 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 zadané položky. 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 hašovací tabulce nebo slovníku: zápis s použitím členské notace nebo notace indexu pole.

  • Notace člena – k hodnotám lze přistupovat prostřednictvím názvu klíče jako vlastnosti členské objektu. Například:

    PS> $hash.1
    one
    
    PS> $dictionary.2
    two
    
  • Notace indexu pole – k hodnotám lze přistupovat pomocí indexové notace. PowerShell převede toto označení na volání parametrizované vlastnosti Item 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. Například:

    PS> $hash['three']
    3
    
    PS> $hash[2]
    two
    

    V tomto příkladu hodnota klíče 2 nepředstavuje index v rámci 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 ve slovnících se hodnota uvnitř závorek interpretuje na základě jejího 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. Napří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 hodnota pole [1] indexem do kolekce hodnot a používá přetíženou parametrizovanou vlastnost Item(int index). Hodnota pole [[Object]1] není index, ale hodnota klíče při použití přetížení Item(System.Object key).

    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í rozhraní System.Collections.IDictionary, například OrderedDictionary.

Iterace nad klíči a hodnotami

Klíče v hashtabuli můžete iterovat, abyste hodnoty mohli zpracovávat několika způsoby. Každý z příkladů v této části má stejný výstup. Iterují přes $hash proměnnou definovanou zde:

$hash = [ordered]@{Number = 1; Shape = "Square"; Color = "Blue"}

Poznámka

V těchto příkladech je $hash definován jako seřazený slovník, aby se zajistilo, ž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 se k iteraci klíčů používá blok foreach.

foreach ($Key in $hash.Keys) {
    "The value of '$Key' is: $($hash[$Key])"
}

V tomto příkladu se k iteraci klíčů používá ForEach-Object.

$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 se používají metody GetEnumerator() a ForEach() k iteraci jednotlivých párů 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 = @{}

Můžete přidat páry klíč-hodnota pomocí notace 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")

Můžete přidat klíče a hodnoty do tabulky hashů pomocí operátoru sčítání (+) a tímto operátorem také přidat jednu tabulku hashů k jiné existující tabulce. 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í nemůžete použít k odebrání páru klíč-hodnota z hashtable, 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 klíč-hodnota Time z $hash.

$hash.Remove("Time")

Typy objektů v hashtables

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 tabulky hash proměnné $p. Klíč je objekt Service, 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, kde klíčem je řetězec "Hash2" a hodnotou 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 hashtable v proměnné $p a potom klíče seřadí podle abecedy.

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 hashovací tabulky vlastností a jejich hodnot.

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 musí být možné je nastavit.

Další informace naleznete v tématu about_Object_Creation.

ConvertFrom-StringData

Rutina ConvertFrom-StringData převede řetězec nebo složený řetězec páry klíč-hodnota na hašovací tabulku. Rutinu ConvertFrom-StringData můžete bezpečně použít v části Data skriptu a můžete ji použít s rutinou Import-LocalizedData k zobrazení uživatelských zpráv v jazykové verzi uživatelského rozhraní aktuálního uživatele.

Here-strings jsou zvlášť užitečné, když hodnoty v hashtable obsahují uvozovky. Další informace o řetězcích zde naleznete 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 proměnné $string.

$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 hashovací tabulku.

ConvertFrom-StringData $string

Name                           Value
----                           -----
Msg3                           Enter an alias (or "nickname").
Msg2                           She said, "Hello, World."
Msg1                           Type "Windows".

Další informace o řetězcích zde naleznete v tématu about_Quoting_Rules.

Viz také