Поделиться через


about_Hash_Tables

Краткое описание

Описывает создание, использование и сортировку хэш-хэш-таблицей в PowerShell.

Подробное описание

А hashtable, также известный как словарь или ассоциативный массив, представляет собой компактную структуру данных, которая хранит одну или несколько пар "ключ-значение". Например, хэш-таблица может содержать ряд IP-адресов и имен компьютеров, где IP-адреса являются ключами, а имена компьютеров — значениями или наоборот.

В PowerShell каждый hashtable объект является [System.Collections.Hashtable] объектом. Свойства и методы Hashtable объектов можно использовать в PowerShell.

Начиная с PowerShell 3.0, можно использовать [ordered] ускоритель типов для создания [System.Collections.Specialized.OrderedDictionary] объекта в PowerShell.

Упорядоченные словари отличаются от хэш-списков, что ключи всегда отображаются в порядке их перечисления. Порядок ключей в объекте hashtable не является детерминированным.

Ключи и значения в хэш-файлах также являются объектами .NET. Они чаще всего являются строками или целыми числами, но они могут иметь любой тип объекта. Можно также создать вложенные хэш-типы, в которых значение ключа является другим hashtable.

Хэш-файлы часто используются, так как они эффективны для поиска и извлечения данных. Хэш-списки можно использовать для хранения списков и создания вычисляемых свойств в PowerShell. ConvertFrom-StringData И командлет преобразует структурированные строковые данные в объектhashtable.

Синтаксис

Синтаксис объекта hashtable выглядит следующим образом:

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

Синтаксис упорядоченного словаря выглядит следующим образом:

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

Акселератор [ordered] типов появился в PowerShell 3.0.

Чтобы создать, hashtableвыполните следующие рекомендации.

  • hashtable Начните с знака (@).
  • Заключите фигурные hashtable скобки ({}).
  • Введите одну или несколько пар "ключ-значение" для содержимого hashtableобъекта.
  • Используйте знак равенства (=) для разделения каждого ключа от его значения.
  • Используйте точку с запятой (;) или разрыв строки для разделения пар "ключ-значение".
  • Ключи, содержащие пробелы, должны быть заключены в кавычки. Значения должны быть допустимыми выражениями PowerShell. Строки должны отображаться в кавычках, даже если они не включают пробелы.
  • Чтобы управлять ими hashtable, сохраните его в переменной.
  • При назначении упорядоченной hashtable переменной поместите [ordered] тип перед символом @ . Если вы поместите его перед именем переменной, команда завершается ошибкой.

Вы можете использовать упорядоченные словари таким же образом, как и хэштебли. Любой тип можно использовать в качестве значения параметров, которые принимают hashtable объекты типа словаря илиiDictionary словаря.

Создание хэш-стилей и упорядоченных словарей

Рассмотрим следующие hashtable и упорядоченные примеры словаря:

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

Как видно, пары "ключ-значение" в ней hashtable не представлены в том порядке, в который они были определены.

Самый простой способ создать упорядоченный словарь — использовать [ordered] атрибут. Поместите атрибут непосредственно перед символом @ .

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

В отличие от хэш-элементов, упорядоченные словари поддерживают порядок значения ключа.

Преобразование хэш-записей и упорядоченных словарей

Нельзя использовать [ordered] акселератор типов для преобразования или приведения hashtable. Если вы помещете упорядоченный атрибут перед именем переменной, команда завершается ошибкой со следующим сообщением об ошибке.

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

Чтобы исправить выражение, переместите атрибут [упорядочено].

$orderedhash = [ordered]@{}

Вы можете привести упорядоченный словарь к объекту hashtable, но вы не можете гарантировать порядок элементов.

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

Hashtable и свойства словаря

Хэш-страницы и упорядоченные словари используют несколько свойств. Рассмотрим $hash и $dictionary переменные, определенные в предыдущих примерах.

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

Наиболее используемыми свойствами являются Count, Key, Values и Item.

  • Свойство Count , указывающее количество пар "ключ-значение" в объекте.

  • Свойство Keys — это коллекция имен ключей в hashtable словаре или в словаре.

    PS> $hash.Keys
    three
    2
    1
    
    PS> $dictionary.Keys
    1
    2
    three
    
  • Свойство Values — это коллекция значений в hashtable словаре или в словаре.

    PS> $hash.Values
    3
    two
    one
    
    PS> $dictionary.Values
    one
    two
    3
    
  • Свойство Item — это параметризованное свойство, которое возвращает значение указанного элемента. Хэштебли используют ключ в качестве параметра для параметризованного свойства, а словари используют индекс по умолчанию. Это различие влияет на доступ к значениям для каждого типа.

Доступ к значениям

Существует два распространенных способа доступа к значениям в нотации элементов или индексации массива.hashtable

  • Нотация элемента. К значениям можно получить доступ с помощью имени ключа в качестве свойства члена объекта. Например:

    PS> $hash.1
    one
    
    PS> $dictionary.2
    two
    
  • Нотация индекса массива. К значениям можно получить доступ с помощью нотации индекса. PowerShell преобразует нотацию в вызов параметризованного свойства Item объекта.

    При использовании нотации индекса с хэш-файлами значение внутри квадратных скобок — это имя ключа. Если ключ является строковым значением, заключите имя ключа в кавычки. Например:

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

    В этом примере ключевое значение 2 не является индексом в коллекции значений. Это значение ключа в паре "ключ-значение". Это можно доказать, индексируя в коллекцию значений.

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

    При использовании нотации индекса с словарями значение внутри квадратных скобок интерпретируется на основе его типа. Если значение является целым числом, оно рассматривается как индекс в коллекции значений. Если значение не является целым числом, оно рассматривается как имя ключа. Например:

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

    В этом примере значение [1] массива представляет собой индекс в коллекцию значений с помощью параметризованной Item(int index) перегрузки свойств. Значение [[object]1] массива не является индексом, а значением ключа с помощью перегрузки Item(System.Object key) .

    Примечание.

    Это поведение может быть запутано, если значение ключа является целым числом. По возможности следует избегать использования целых значений ключей в словарях.

Обработка конфликтов имен свойств

Если имя ключа сталкивается с одним из имен HashTable свойств типа, можно использовать встроенный элемент psbase для доступа к этим свойствам. Например, если имя ключа и keys вы хотите вернуть коллекцию ключей HashTable , используйте следующий синтаксис:

$hashtable.psbase.Keys

Это требование применяется для других типов, реализующих System.Collections.IDictionary интерфейс, например OrderedDictionary.

Итерирование ключей и значений

Вы можете выполнить итерацию по ключам, hashtable чтобы обрабатывать значения несколькими способами. Каждый из примеров в этом разделе имеет одинаковые выходные данные. Они выполняют итерацию по переменной, определенной $hash здесь:

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

Примечание.

В этих примерах определяется как упорядоченный словарь, чтобы гарантировать, $hash что выходные данные всегда совпадают. Эти примеры работают одинаково для стандартных хэш-элементов, но порядок выходных данных не предсказуем.

Каждый пример возвращает сообщение для каждого ключа и его значения:

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

В этом примере используется foreach блок для итерации ключей.

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

В этом примере используется ForEach-Object для итерации ключей.

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

В этом примере метод используется для отправки GetEnumerator() каждой пары "ключ-значение" через конвейер ForEach-Object.

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

В этом примере используются GetEnumerator() методы итерации ForEach() по каждой паре "ключ-значение".

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

Добавление и удаление ключей и значений

Как правило, при создании hashtable пары "ключ-значение" включаются в определение. Однако вы можете добавлять и удалять пары "ключ-значение" в hashtable любое время. В следующем примере создается пустое hashtable.

$hash = @{}

Пары "ключ-значение" можно добавлять с помощью нотации массива. Например, в следующем примере добавляется Time ключ со значением Now .hashtable

$hash["Time"] = "Now"

Вы также можете добавить ключи и значения в hashtable Add() метод System.Collections.Hashtable объекта. Метод Add() имеет следующий синтаксис:

Add(Key, Value)

Например, чтобы добавить Time ключ со значением Now в значение, hashtableиспользуйте следующий формат инструкции.

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

Кроме того, можно добавить ключи и значения в hashtable оператор сложения (+) для добавления hashtable в существующий hashtableобъект. Например, следующая инструкция добавляет Time ключ со значением Now hashtable в $hash переменную.

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

Можно также добавить значения, хранящиеся в переменных.

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

$hash.Add($t, $now)

Оператор вычитания нельзя использовать для удаления пары "ключ-значение" из хэш-таблицы, но можно использовать Remove() метод hashtable объекта. Метод Remove имеет следующий синтаксис:

$object.Remove(<key>)

В следующем примере удаляется Time пара "ключ-значение" из $hash.

$hash.Remove("Time")

Типы объектов в hashTables

Ключи и значения в объекте hashtable .NET могут иметь любой тип объекта .NET, а один hashtable может иметь ключи и значения нескольких типов.

Следующая инструкция создает hashtable строки имени процесса и значения объектов процесса и сохраняет его в переменной $p .

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

Вы можете отобразить hashtable $p и использовать свойства имени ключа для отображения значений.

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

Ключи в объекте могут быть любым типом hashtable .NET. Следующая инструкция добавляет пару "ключ-значение" в hashtable $p переменную. Ключ — это объект службы , представляющий службу WinRM, а значение — текущее состояние службы.

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

Вы можете отобразить и получить доступ к новой паре "ключ-значение", используя те же методы, которые используются для других пар в .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

Ключи и значения в объекте hashtable также могут быть Hashtable объектами. Следующая инструкция добавляет пару hashtable "ключ-значение" в $p переменную, в которой ключ является строкой, Hash2 и значением является hashtable три пары "ключ-значение".

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

Вы можете отображать и получать доступ к новым значениям, используя те же методы.

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

Сортировка ключей и значений

Элементы в объекте hashtable внутренне неупорядочены. Пары "ключ-значение" могут отображаться в другом порядке при каждом отображении.

Хотя вы не можете сортировать hashtable, можно использовать GetEnumerator() метод хэш-таблицы для перечисления ключей и значений, а затем использовать Sort-Object командлет для сортировки перечисленных значений для отображения.

Например, следующие команды перечисляют ключи и значения в хэш-таблице в переменной $p , а затем сортируют ключи в алфавитном порядке.

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

Следующая команда использует ту же процедуру для сортировки хэш-значений в порядке убывания.

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

Создание объектов из хэш-элементов

Начиная с PowerShell 3.0, можно создать объект из hashtable свойств и значений свойств.

Синтаксис выглядит следующим образом:

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

Этот метод работает только для классов, имеющих конструктор без параметров. Свойства объекта должны быть общедоступными и наборными.

Дополнительные сведения см. в about_Object_Creation.

ConvertFrom-StringData

Командлет ConvertFrom-StringData преобразует строку или приведенную здесь строку пар "ключ-значение" в строку hashtable. Командлет можно безопасно использовать ConvertFrom-StringData в разделе "Данные" скрипта, и его можно использовать с Import-LocalizedData командлетом для отображения сообщений пользователей в языке и региональных параметрах пользовательского интерфейса текущего пользователя.

Здесь строки особенно полезны, если значения в hashtable кавычках включаются. Дополнительные сведения о строках см. в about_Quoting_Rules.

В следующем примере показано, как создать здесь строку сообщений пользователя в предыдущем примере и как ConvertFrom-StringData использовать их для преобразования из строки в строку hashtable.

Следующая команда создает здесь строку пар "ключ-значение", а затем сохраняет ее в переменной $string .

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

Эта команда использует ConvertFrom-StringData командлет для преобразования строки здесь в строку hashtable.

ConvertFrom-StringData $string

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

Дополнительные сведения о строках см. в about_Quoting_Rules.

См. также