Udostępnij za pośrednictwem


about_Hash_Tables

Krótki opis

Opisuje sposób tworzenia, używania i sortowania tabel skrótów w programie PowerShell.

Długi opis

Obiekt hashtable, znany również jako słownik lub tablica asocjacyjna, to kompaktowa struktura danych, która przechowuje co najmniej jedną parę klucz-wartość. Na przykład tabela skrótów może zawierać serię adresów IP i nazw komputerów, gdzie adresy IP są kluczami, a nazwy komputerów są wartościami lub odwrotnie.

W programie PowerShell każdy hashtable z nich jest obiektem [System.Collections.Hashtable] . Właściwości i metody Hashtable obiektów można używać w programie PowerShell.

Począwszy od programu PowerShell 3.0, możesz użyć akceleratora [ordered] typów do utworzenia [System.Collections.Specialized.OrderedDictionary] obiektu w programie PowerShell.

Uporządkowane słowniki różnią się od tabel skrótów, dlatego klucze są zawsze wyświetlane w kolejności ich wyświetlania. Kolejność kluczy w obiekcie hashtable nie jest deterministyczna.

Klucze i wartość w tabelach skrótów są również obiektami platformy .NET. Są to najczęściej ciągi lub liczby całkowite, ale mogą mieć dowolny typ obiektu. Można również utworzyć zagnieżdżone tabele skrótów, w których wartość klucza jest kolejną hashtablewartością .

Tabele skrótów są często używane, ponieważ są wydajne do znajdowania i pobierania danych. Tabele skrótów umożliwiają przechowywanie list i tworzenie właściwości obliczeniowych w programie PowerShell. ConvertFrom-StringData Polecenie cmdlet konwertuje dane ciągów strukturalnych na hashtable.

Składnia

Składnia elementu hashtable jest następująca:

@{ <name> = <value>; [<name> = <value> ] ...}

Składnia uporządkowanego słownika jest następująca:

[ordered]@{ <name> = <value>; [<name> = <value> ] ...}

Akcelerator [ordered] typów został wprowadzony w programie PowerShell 3.0.

Aby utworzyć element hashtable, postępuj zgodnie z następującymi wytycznymi:

  • Rozpocznij znak hashtable od znaku (@).
  • hashtable Ujęte w nawiasy klamrowe ({}).
  • Wprowadź co najmniej jedną parę klucz-wartość dla zawartości elementu hashtable.
  • Użyj znaku równości (=), aby oddzielić każdy klucz od jego wartości.
  • Użyj średnika (;) lub podziału wiersza, aby oddzielić pary klucz-wartość.
  • Klucze zawierające spacje muszą być ujęte w znaki cudzysłowu. Wartości muszą być prawidłowymi wyrażeniami programu PowerShell. Ciągi muszą być wyświetlane w cudzysłowie, nawet jeśli nie zawierają spacji.
  • Aby zarządzać elementem hashtable, zapisz go w zmiennej.
  • Podczas przypisywania uporządkowanej hashtable do zmiennej umieść [ordered] typ przed symbolem @ . Jeśli umieścisz ją przed nazwą zmiennej, polecenie zakończy się niepowodzeniem.

Można użyć uporządkowanych słowników w taki sam sposób, jak w przypadku używania tabel skrótów. Typ może służyć jako wartość parametrów, które przyjmują hashtable obiekty typu lub (iDictionary).

Tworzenie tabel skrótów i uporządkowanych słowników

Rozważmy następujące hashtable i uporządkowane przykłady słowników:

$hash = @{
    1       = 'one'
    2       = 'two'
    'three' = 3
}
$hash
Name                           Value
----                           -----
three                          3
2                              two
1                              one

Jak widać, pary klucz-wartość w obiekcie hashtable nie są prezentowane w kolejności, w której zostały zdefiniowane.

Najprostszym sposobem utworzenia uporządkowanego słownika jest użycie atrybutu [ordered] . Umieść atrybut bezpośrednio przed symbolem @ .

$dictionary = [ordered]@{
    1       = 'one'
    2       = 'two'
    'three' = 3
}
$dictionary
Name                           Value
----                           -----
1                              one
2                              two
three                          3

W przeciwieństwie do tabel skrótów uporządkowane słowniki zachowują kolejność klucz-wartość.

Konwertowanie tabel skrótów i uporządkowanych słowników

Nie można użyć akceleratora [ordered] typów do konwersji ani rzutowania elementu hashtable. Jeśli umieścisz uporządkowany atrybut przed nazwą zmiennej, polecenie zakończy się niepowodzeniem z następującym komunikatem o błędzie.

[ordered]$orderedhash = @{}
ParserError:
Line |
   1 |  [ordered]$orderedhash = @{}
     |  ~~~~~~~~~~~~~~
     | The ordered attribute can be specified only on a hash literal node.

Aby poprawić wyrażenie, przenieś atrybut [uporządkowany].

$orderedhash = [ordered]@{}

Można rzutować uporządkowany słownik na hashtableelement , ale nie można zagwarantować kolejności elementów członkowskich.

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

Hashtable i właściwości słownika

Tabele skrótów i uporządkowane słowniki mają kilka właściwości. Rozważ zmienne $hash i $dictionary zdefiniowane w poprzednich przykładach.

$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;}

Najczęściej używane właściwości to Liczba, Klucze, Wartości i Element.

  • Właściwość Count wskazująca liczbę par klucz-wartość w obiekcie.

  • Właściwość Keys jest kolekcją nazw kluczy w słowniku hashtable lub .

    PS> $hash.Keys
    three
    2
    1
    
    PS> $dictionary.Keys
    1
    2
    three
    
  • Właściwość Values jest kolekcją wartości w słowniku hashtable lub .

    PS> $hash.Values
    3
    two
    one
    
    PS> $dictionary.Values
    one
    two
    3
    
  • Właściwość Item jest właściwością sparametryzowaną, która zwraca wartość określonego elementu. Tabele skrótów używają klucza jako parametru do sparametryzowanej właściwości, podczas gdy słowniki domyślnie używają indeksu. Ta różnica wpływa na sposób uzyskiwania dostępu do wartości dla każdego typu.

Uzyskiwanie dostępu do wartości

Istnieją dwa typowe sposoby uzyskiwania dostępu do wartości w słowniku hashtable lub: notacja składowa lub notacja indeksu tablicy.

  • Notacja składowa — można uzyskać dostęp do wartości przy użyciu nazwy klucza jako właściwości składowej obiektu. Na przykład:

    PS> $hash.1
    one
    
    PS> $dictionary.2
    two
    
  • Notacja indeksu tablicowego — dostęp do wartości można uzyskać przy użyciu notacji indeksu. Program PowerShell konwertuje notację na wywołanie właściwości sparametryzowanej elementu obiektu.

    Jeśli używasz notacji indeksu z tabelami skrótów, wartość wewnątrz nawiasów jest nazwą klucza. Jeśli klucz jest wartością ciągu, należy ująć nazwę klucza w cudzysłowy. Na przykład:

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

    W tym przykładzie wartość 2 klucza nie jest indeksem w kolekcji wartości. Jest to wartość klucza w parze klucz-wartość. Możesz to udowodnić, indeksując w kolekcji wartości.

    PS> ([array]$hash.Values)[2]
    one
    

    W przypadku używania notacji indeksu z słownikami wartość wewnątrz nawiasów jest interpretowana na podstawie jego typu. Jeśli wartość jest liczbą całkowitą, jest traktowana jako indeks do kolekcji wartości. Jeśli wartość nie jest liczbą całkowitą, jest traktowana jako nazwa klucza. Na przykład:

    PS> $dictionary[1]
    two
    PS> ([array]$dictionary.Values)[1]
    two
    PS> $dictionary[[object]1]
    one
    PS> $dictionary['three']
    3
    

    W tym przykładzie wartość [1] tablicy jest indeksem do kolekcji wartości przy użyciu przeciążenia sparametryzowanej Item(int index) właściwości. Wartość [[object]1] tablicy nie jest indeksem, ale wartością klucza używającą Item(System.Object key) przeciążenia.

    Uwaga

    To zachowanie może być mylące, gdy wartość klucza jest liczbą całkowitą. Jeśli to możliwe, należy unikać używania wartości klucza całkowitego w słownikach.

Obsługa kolizji nazw właściwości

Jeśli nazwa klucza zderza się z jedną z nazw HashTable właściwości typu, możesz użyć wewnętrznego elementu członkowskiego psbase, aby uzyskać dostęp do tych właściwości. Jeśli na przykład nazwa klucza to keys i chcesz zwrócić kolekcję kluczy, użyj następującej HashTable składni:

$hashtable.psbase.Keys

To wymaganie dotyczy innych typów, które implementują System.Collections.IDictionary interfejs, na przykład OrderedDictionary.

Iterowanie kluczy i wartości

W celu przetworzenia wartości na kilka sposobów można wykonać iterację po kluczach hashtable . Każdy z przykładów w tej sekcji ma identyczne dane wyjściowe. Iterują one zmienną zdefiniowaną $hash tutaj:

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

Uwaga

W tych przykładach jest definiowany jako uporządkowany słownik, aby upewnić się, $hash że dane wyjściowe są zawsze w tej samej kolejności. Te przykłady działają tak samo w przypadku standardowych tabel skrótów, ale kolejność danych wyjściowych nie jest przewidywalna.

Każdy przykład zwraca komunikat dla każdego klucza i jego wartości:

The value of 'Number' is: 1
The value of 'Shape' is: Square
The value of 'Color' is: Blue

W tym przykładzie użyto foreach bloku do iterowania kluczy.

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

W tym przykładzie użyto ForEach-Object metody do iterowania kluczy.

$hash.Keys | ForEach-Object {
    "The value of '$_' is: $($hash[$_])"
}

W tym przykładzie użyto GetEnumerator() metody do wysyłania każdej pary klucz-wartość za pośrednictwem potoku do ForEach-Objectmetody .

$hash.GetEnumerator() | ForEach-Object {
    "The value of '$($_.Key)' is: $($_.Value)"
}

W tym przykładzie użyto GetEnumerator() metod i ForEach() do iterowania poszczególnych par klucz-wartość.

$hash.GetEnumerator().ForEach({"The value of '$($_.Key)' is: $($_.Value)"})

Dodawanie i usuwanie kluczy i wartości

Zazwyczaj podczas tworzenia hashtable pary klucz-wartość są uwzględniane w definicji. Można jednak w dowolnym momencie dodawać i usuwać pary klucz-wartość.hashtable Poniższy przykład tworzy pusty hashtableelement .

$hash = @{}

Pary klucz-wartość można dodawać przy użyciu notacji tablicy. Na przykład poniższy przykład dodaje Time klucz z wartością Now do elementu hashtable.

$hash["Time"] = "Now"

Możesz również dodać klucze i wartości do hashtable obiektu przy użyciu Add() metody System.Collections.Hashtable . Metoda Add() ma następującą składnię:

Add(Key, Value)

Aby na przykład dodać Time klucz z wartością Now do hashtableklasy , użyj następującego formatu instrukcji.

$hash.Add("Time", "Now")

Możesz również dodać klucze i wartości do hashtable elementu przy użyciu operatora dodawania (+), aby dodać element hashtable do istniejącego hashtableelementu . Na przykład poniższa instrukcja dodaje Time klucz z wartością Now w hashtable zmiennej $hash .

$hash = $hash + @{Time="Now"}

Możesz również dodać wartości przechowywane w zmiennych.

$t = "Today"
$now = (Get-Date)

$hash.Add($t, $now)

Nie można użyć operatora odejmowania, aby usunąć parę klucz-wartość z tabeli skrótówhashtable, ale można użyć Remove() metody obiektu. Metoda Remove ma następującą składnię:

$object.Remove(<key>)

Poniższy przykład usuwa Time parę klucz-wartość z $hashklasy .

$hash.Remove("Time")

Typy obiektów w tabelach skrótów

Klucze i wartości w obiekcie hashtable mogą mieć dowolny typ obiektu .NET, a jeden hashtable może mieć klucze i wartości wielu typów.

Poniższa instrukcja tworzy hashtable ciągi nazw procesów i przetwarza wartości obiektów i zapisuje je w zmiennej $p .

$p = @{
    "PowerShell" = (Get-Process PowerShell)
    "Notepad" = (Get-Process notepad)
}

Możesz wyświetlić hashtable element w $p pliku i użyć właściwości nazwa-klucza, aby wyświetlić wartości.

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

Klucze w obiekcie mogą być dowolnym typem hashtable platformy .NET. Poniższa instrukcja dodaje parę klucz-wartość do hashtable zmiennej w zmiennej $p . Klucz jest obiektem usługi, który reprezentuje usługę WinRM, a wartość jest bieżącym stanem usługi.

$p = $p + @{
    (Get-Service WinRM) = ((Get-Service WinRM).Status)
}

Możesz wyświetlić nową parę klucz-wartość i uzyskać do nich dostęp przy użyciu tych samych metod, które są używane dla innych par w obiekcie 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

Klucze i wartości w obiekcie hashtable mogą być Hashtable również obiektami. Poniższa instrukcja dodaje parę klucz-wartość do hashtable zmiennej, $p w której klucz jest ciągiem, hash2, a wartość jest hashtable z trzema parami klucz-wartość.

$p = $p + @{
    "Hash2"= @{a=1; b=2; c=3}
}

Możesz wyświetlać i uzyskiwać dostęp do nowych wartości przy użyciu tych samych metod.

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

Sortowanie kluczy i wartości

Elementy w obiekcie hashtable są wewnętrznie nieurządkowane. Pary klucz-wartość mogą być wyświetlane w innej kolejności za każdym razem, gdy są wyświetlane.

Chociaż nie można posortować hashtableelementu , możesz użyć GetEnumerator() metody skrótów, aby wyliczyć klucze i wartości, a następnie użyć Sort-Object polecenia cmdlet , aby posortować wyliczone wartości do wyświetlenia.

Na przykład następujące polecenia wyliczają klucze i wartości w tabeli skrótów w zmiennej $p , a następnie sortują klucze w kolejności alfabetycznej.

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

Poniższe polecenie używa tej samej procedury, aby posortować wartości skrótu w kolejności malejącej.

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

Tworzenie obiektów na podstawie tabel skrótów

Począwszy od programu PowerShell 3.0, można utworzyć obiekt na podstawie hashtable wartości właściwości i właściwości.

Składnia wygląda następująco:

[<class-name>]@{
  <property-name>=<property-value>
  <property-name>=<property-value>
}

Ta metoda działa tylko w przypadku klas, które mają konstruktor, który nie ma parametrów. Właściwości obiektu muszą być publiczne i konfigurowalne.

Aby uzyskać więcej informacji, zobacz about_Object_Creation.

ConvertFrom-StringData

Polecenie ConvertFrom-StringData cmdlet konwertuje ciąg lub ciąg here-string par klucz-wartość na hashtable. Możesz bezpiecznie użyć ConvertFrom-StringData polecenia cmdlet w sekcji Dane skryptu i użyć go z Import-LocalizedData poleceniem cmdlet do wyświetlania komunikatów użytkownika w kulturze interfejsu użytkownika bieżącego użytkownika.

Ciągi tutaj są szczególnie przydatne, gdy wartości w znakach cudzysłowu hashtable dołączania. Aby uzyskać więcej informacji na temat ciągów tutaj, zobacz about_Quoting_Rules.

W poniższym przykładzie pokazano, jak utworzyć tutaj ciąg komunikatów użytkownika w poprzednim przykładzie i jak użyć polecenia ConvertFrom-StringData , aby przekonwertować je z ciągu na hashtable.

Następujące polecenie tworzy tutaj ciąg par klucz-wartość, a następnie zapisuje je w zmiennej $string .

$string = @"
Msg1 = Type "Windows".
Msg2 = She said, "Hello, World."
Msg3 = Enter an alias (or "nickname").
"@

To polecenie używa ConvertFrom-StringData polecenia cmdlet , aby przekonwertować tutaj-ciąg na hashtable.

ConvertFrom-StringData $string

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

Aby uzyskać więcej informacji na temat ciągów tutaj, zobacz about_Quoting_Rules.

Zobacz też