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.
См. также
PowerShell