о хеш-таблицах


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

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

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

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

В PowerShell каждая хеш-таблица представляет собой объект Hashtable [System.Collections.Hashtable]. Вы можете использовать свойства и методы объектов Hashtable в PowerShell.

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

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

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

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

Синтаксис

Синтаксис хеш-таблицы следующий:

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

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

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

Ускоритель типа [ordered] был представлен в PowerShell 3.0.

Создание хеш-таблиц

Чтобы создать хеш-таблицу, следуйте этим рекомендациям:

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

Чтобы создать пустую хеш-таблицу со значением $hash, введите:

$hash = @{}

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

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

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

Вы можете создать упорядоченный словарь, добавив объект типа OrderedDictionary, но самый простой способ создать упорядоченный словарь — использовать атрибут [ordered].

Атрибут [ordered] представлен в PowerShell 3.0.

Поместите атрибут непосредственно перед символом «@».

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

Вы можете использовать упорядоченные словари так же, как и хеш-таблицы. Любой тип можно использовать в качестве значения параметров, принимающих хеш-таблицу или словарь (iDictionary).

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

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

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

$hash = [ordered]@{}

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

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

Отображение хеш-таблиц

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

$hash
Name                           Value
----                           -----
Shape                          Square
Color                          Blue
Number                         1

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

$hash.keys
Number
Shape
Color
$hash.values
1
Square
Blue

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

$hashtable.<key>
<value>

Например:

$hash.Number
1

$hash.Color
Blue

хэш-таблицы имеют свойство Count, которое указывает количество пар ключ-значение в хеш-таблице.

$hash.count
3

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

Например:

$hash["Number"]
1

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

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

$hashtable.psbase.Keys

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

Перебор ключей и значений

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

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

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

$hash["<key>"] = "<value>"

Например, чтобы добавить в хеш-таблицу ключ «Время» со значением «Сейчас», используйте следующий формат инструкции.

$hash["Time"] = "Now"

Вы также можете добавить ключи и значения в хеш-таблицу, используя метод Add объекта System.Collections.Hashtable. Метод Add имеет следующий синтаксис:

Add(Key, Value)

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

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

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

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

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

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

$hash.Add($t, $now)

Вы не можете использовать оператор вычитания для удаления пары ключ-значение из хеш-таблицы, но вы можете использовать метод Remove объекта Hashtable. Метод Remove принимает ключ в качестве значения.

Метод Remove имеет следующий синтаксис:

Remove(Key)

Например, чтобы удалить пару ключ-значение Time=Now из хеш-таблицы в значении переменной $hash, введите:

$hash.Remove("Time")

Вы можете использовать все свойства и методы объектов Hashtable в PowerShell, включая Contains, Clear, Clone и CopyTo. Дополнительные сведения об объектах Hashtable см. в разделе System.Collections.Hashtable.

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

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

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

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

Вы можете отобразить хеш-таблицу в $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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Начиная с PowerShell 3.0, вы можете создать объект из хеш-таблицы свойств и значений свойств.

Синтаксис следующий:

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

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

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

ConvertFrom-StringData

Командлет ConvertFrom-StringData преобразует строку или следующую строку пар ключ-значение в хеш-таблицу. Вы можете безопасно использовать командлет ConvertFrom-StringData в разделе «Данные» сценария, а также использовать его с командлетом Import-LocalizedData для отображения пользовательских сообщений в пользовательском интерфейсе. культура интерфейса (UI) текущего пользователя.

Строки здесь особенно полезны, когда значения в хеш-таблице заключены в кавычки. Дополнительные сведения о строках см. в разделе about_Quoting_Rules.

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

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

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

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

ConvertFrom-StringData $string

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

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

См. также

  • about_Arrays
  • about_Intrinsic_Members
  • about_Object_Creation
  • about_Quoting_Rules
  • about_Script_Internationalization
  • Import-LocalizedData
  • ConvertFrom-StringData
  • System.Collections.Hashtable