Сведения о хэш-таблицах
КРАТКОЕ ОПИСАНИЕ
Описывает создание, использование и сортировку хэш-таблиц в PowerShell.
ПОДРОБНОЕ ОПИСАНИЕ
Хэш-таблица, также называемая словарем или ассоциативным массивом, представляет собой компактную структуру данных, в котором хранится одна или несколько пар "ключ-значение". Например, хэш-таблица может содержать ряд IP-адресов и имен компьютеров, где IP-адреса являются ключами, а имена компьютеров — значениями или наоборот.
В PowerShell каждая хэш-таблица является объектом Hashtable (System.Collections.Hashtable). Свойства и методы объектов Hashtable можно использовать в PowerShell.
Начиная с PowerShell 3.0, вы можете использовать атрибут [упорядочено] для создания упорядоченного словаря (System.Collections.Specialized.OrderedDictionary) в PowerShell.
Упорядоченные словари отличаются от хэш-таблиц тем, что ключи всегда отображаются в порядке их перечисления. Порядок ключей в хэш-таблице не определен.
Ключи и значения в хэш-таблицах также являются объектами .NET. Чаще всего это строки или целые числа, но они могут иметь любой тип объекта. Можно также создать вложенные хэш-таблицы, в которых значение ключа является другой хэш-таблицей.
Хэш-таблицы часто используются, так как они очень эффективны для поиска и извлечения данных. Хэш-таблицы можно использовать для хранения списков и создания вычисляемых свойств в PowerShell. Кроме того, в PowerShell есть командлет ConvertFrom-StringData, который преобразует строки в хэш-таблицу.
Синтаксис
Синтаксис хэш-таблицы выглядит следующим образом:
@{ <name> = <value>; [<name> = <value> ] ...}
Синтаксис упорядоченного словаря выглядит следующим образом:
[ordered]@{ <name> = <value>; [<name> = <value> ] ...}
Атрибут [упорядочено] появился в PowerShell 3.0.
Создание хэш-таблиц
Чтобы создать хэш-таблицу, следуйте приведенным ниже рекомендациям.
- Начните хэш-таблицу со знака at (@).
- Заключите хэш-таблицу в фигурные скобки ({}).
- Введите одну или несколько пар "ключ-значение" для содержимого хэш-таблицы.
- Используйте знак равенства (=), чтобы отделить каждый ключ от его значения.
- Используйте точку с запятой (;) или разрыв строки для разделения пар "ключ-значение".
- Ключ, содержащий пробелы, должен быть заключен в кавычки. Значения должны быть допустимыми выражениями PowerShell. Строки должны отображаться в кавычках, даже если они не содержат пробелов.
- Чтобы управлять хэш-таблицей, сохраните ее в переменной.
- При назначении упорядоченной хэш-таблицы переменной поместите атрибут [упорядоченный] перед символом "@". Если поместить его перед именем переменной, команда завершается ошибкой.
Чтобы создать пустую хэш-таблицу в значении $hash, введите:
$hash = @{}
Вы также можете добавить ключи и значения в хэш-таблицу при ее создании. Например, следующая инструкция создает хэш-таблицу с тремя ключами.
$hash = @{ Number = 1; Shape = "Square"; Color = "Blue"}
Создание упорядоченных словарей
Вы можете создать упорядоченный словарь, добавив объект типа OrderedDictionary, но самый простой способ создать упорядоченный словарь — использовать атрибут [Упорядочено].
Атрибут [упорядочен] появился в PowerShell 3.0.
Поместите атрибут непосредственно перед символом "@".
$hash = [ordered]@{ Number = 1; Shape = "Square"; Color = "Blue"}
Упорядоченные словари можно использовать так же, как и хэш-таблицы. Любой тип можно использовать в качестве значения параметров, которые принимают хэш-таблицу или словарь (iDictionary).
Атрибут [упорядочено] нельзя использовать для преобразования или приведения хэш-таблицы. Если поместить упорядоченный атрибут перед именем переменной, команда завершается ошибкой со следующим сообщением об ошибке.
PS C:\> [ordered]$hash = @{}
At line:1 char:1
+ [ordered]$hash = @{}
+ [!INCLUDE[]()]
The ordered attribute can be specified only on a hash literal node.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordExc
eption
+ FullyQualifiedErrorId : OrderedAttributeOnlyOnHashLiteralNode
Чтобы исправить выражение, переместите атрибут [упорядочено].
PS C:\> $hash = [ordered]@{}
Вы можете привести упорядоченный словарь к хэш-таблице, но не сможете восстановить упорядоченный атрибут, даже если очистить переменную и ввести новые значения. Чтобы восстановить порядок, необходимо удалить и повторно создать переменную.
PS C:\> [hashtable]$hash = [ordered]@{
>> Number = 1; Shape = "Square"; Color = "Blue"}
PS C:\> $hash
Name Value
---- -----
Color Blue
Shape Square
Number 1
Отображение хэш-таблиц
Чтобы отобразить хэш-таблицу, сохраненную в переменной, введите имя переменной. По умолчанию хэш-таблицы отображаются в виде таблицы с одним столбцом для ключей и одним столбцом для значений.
C:\PS> $hash
Name Value
---- -----
Shape Square
Color Blue
Number 1
Хэш-таблицы имеют свойства Keys и Values. Используйте точечное нотирование для отображения всех ключей или всех значений.
C:\PS> $hash.keys
Number
Shape
Color
C:\PS> $hash.values
1
Square
Blue
Каждое имя ключа также является свойством хэш-таблицы, а его значением является значение свойства key-name. Используйте следующий формат для отображения значений свойств.
$hashtable.<key>
<value>
Пример:
C:\PS> $hash.Number
1
C:\PS> $hash.Color
Blue
Если имя ключа сталкивается с одним из имен свойств типа HashTable, можно использовать для PSBase
доступа к этим свойствам. Например, если имя ключа — keys
и вы хотите вернуть коллекцию Ключей, используйте следующий синтаксис:
$hashtable.PSBase.Keys
Хэш-таблицы имеют свойство Count, указывающее количество пар "ключ-значение" в хэш-таблице.
C:\PS> $hash.count
3
Таблицы хэш-таблиц не являются массивами, поэтому нельзя использовать целое число в качестве индекса в хэш-таблице, но для индексирования в хэш-таблице можно использовать имя ключа. Если ключ является строковым значением, заключите имя ключа в кавычки.
Пример:
C:\PS> $hash["Number"]
1
Добавление и удаление ключей и значений
Чтобы добавить ключи и значения в хэш-таблицу, используйте следующий формат команды.
$hash["<key>"] = "<value>"
Например, чтобы добавить ключ Time со значением Now в хэш-таблицу, используйте следующий формат инструкции.
$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, а отдельная хэш-таблица может иметь ключи и значения нескольких типов.
Следующая инструкция создает хэш-таблицу строк имен процессов и значений объектов process и сохраняет ее в переменной $p
.
$p = @{"PowerShell" = (Get-Process PowerShell);
"Notepad" = (Get-Process notepad)}
Вы можете отобразить хэш-таблицу в $p
и использовать свойства key-name для отображения значений.
C:\PS> $p
Name Value
---- -----
PowerShell System.Diagnostics.Process (PowerShell)
Notepad System.Diagnostics.Process (notepad)
C:\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
C:\PS> $p.keys | foreach {$p.$_.handles}
441
251
Ключи в хэш-таблице также могут быть любого типа .NET. Следующая инструкция добавляет пару "ключ-значение" в хэш-таблицу в переменной $p
. Ключ — это объект Service, представляющий службу WinRM, а значение — текущее состояние службы.
C:\PS> $p = $p + @{(Get-Service WinRM) = ((Get-Service WinRM).Status)}
Вы можете отобразить новую пару "ключ-значение" и получить к ней доступ, используя те же методы, что и для других пар в хэш-таблице.
C:\PS> $p
Name Value
---- -----
PowerShell System.Diagnostics.Process (PowerShell)
Notepad System.Diagnostics.Process (notepad)
System.ServiceProcess.Servi... Running
C:\PS> $p.keys
PowerShell
Notepad
Status Name DisplayName
------ ---- -----------
Running winrm Windows Remote Management (WS-Manag...
C:\PS> $p.keys | foreach {$_.name}
winrm
Ключи и значения в хэш-таблице также могут быть хэш-таблицами. Следующая инструкция добавляет пару "ключ-значение" в хэш-таблицу в $p
переменной, в которой ключ является строкой, hash2, а значение — хэш-таблицей с тремя парами "ключ-значение".
C:\PS> $p = $p + @{"Hash2"= @{a=1; b=2; c=3}}
Вы можете отобразить новые значения и получить к ней доступ, используя те же методы.
C:\PS> $p
Name Value
---- -----
PowerShell System.Diagnostics.Process (PowerShell)
Notepad System.Diagnostics.Process (notepad)
System.ServiceProcess.Servi... Running
Hash2 {a, b, c}
C:\PS> $p.Hash2
Name Value
---- -----
a 1
b 2
c 3
C:\PS> $p.Hash2.b
2
Сортировка ключей и значений
Элементы в хэш-таблице по своей сути неупорядочены. Пары "ключ-значение" могут отображаться в другом порядке при каждом их отображении.
Хотя хэш-таблицу нельзя отсортировать, можно использовать метод GetEnumerator хэш-таблиц для перечисления ключей и значений, а затем использовать командлет Sort-Object для сортировки перечисленных значений для отображения.
Например, следующие команды перечисляют ключи и значения в хэш-таблице в переменной $p
, а затем сортируют ключи в алфавитном порядке.
C:\PS> $p.GetEnumerator() | Sort-Object -Property key
Name Value
---- -----
Notepad System.Diagnostics.Process (notepad)
PowerShell System.Diagnostics.Process (PowerShell)
System.ServiceProcess.Servi... Running
Следующая команда использует ту же процедуру для сортировки хэш-значений в порядке убывания.
C:\PS> $p.getenumerator() | Sort-Object -Property Value -Descending
Name Value
---- -----
PowerShell System.Diagnostics.Process (PowerShell)
Notepad System.Diagnostics.Process (notepad)
System.ServiceProcess.Servi... Running
Создание объектов из хэш-таблиц
Начиная с PowerShell 3.0 можно создавать объект из хэш-таблицы свойств и значений свойств.
Синтаксис выглядит следующим образом:
[<class-name>]@{
<property-name>=<property-value>
<property-name>=<property-value>
}
Этот метод работает только для классов, имеющих конструктор NULL, то есть конструктор без параметров. Свойства объекта должны быть открытыми и задаваться.
Дополнительные сведения см. в разделе about_Object_Creation.
ConvertFrom-StringData
Командлет ConvertFrom-StringData
преобразует строку или строку здесь пар "ключ-значение" в хэш-таблицу. Командлет можно безопасно использовать ConvertFrom-StringData
в разделе Данные скрипта, а также с командлетом Import-LocalizedData
для отображения пользовательских сообщений в языке и региональных параметрах пользовательского интерфейса текущего пользователя.
Строки здесь особенно полезны, если значения в хэш-таблице содержат кавычки. Дополнительные сведения о строках здесь см. в разделе about_Quoting_Rules.
В следующем примере показано, как создать строку здесь сообщений пользователя в предыдущем примере и как использовать ConvertFrom-StringData
их для их преобразования из строки в хэш-таблицу.
Следующая команда создает строку здесь для пар "ключ-значение", а затем сохраняет ее в переменной $string.
C:\PS> $string = @"
Msg1 = Type "Windows".
Msg2 = She said, "Hello, World."
Msg3 = Enter an alias (or "nickname").
"@
Эта команда использует командлет ConvertFrom-StringData для преобразования строки here в хэш-таблицу.
C:\PS> ConvertFrom-StringData $string
Name Value
---- -----
Msg3 Enter an alias (or "nickname").
Msg2 She said, "Hello, World."
Msg1 Type "Windows".
Дополнительные сведения о строках здесь см. в разделе about_Quoting_Rules.