使用 PowerShell 哈希表的初学者指南

第一次接触哈希表时,您可能会想知道它们是什么,以及它们如何在您的脚本或命令中发挥关键作用。不用担心!本教程将帮助您开始使用 PowerShell 哈希表。

简而言之,哈希表允许您使用键值对存储和操作数据,可以快速高效地访问。在本教程中,您将学习哈希表的基础知识,以及如何在 PowerShell 脚本和命令中使用它们。

继续阅读,开始扩展您的 PowerShell 哈希表技能!

先决条件

本教程将进行实践演示。请确保您的系统已安装并配置了 PowerShell v5+。本教程使用 Windows 10,并搭配 PowerShell 7,但其他版本的 PowerShell 和 Windows 也适用。

创建 PowerShell 哈希表

在某些情况下,检索特定数据可能会变成“大海捞针”。但是使用哈希表,您可以在庞大的数据集中快速搜索特定项。

在 PowerShell 中,哈希表是灵活的数据结构,可以用于多种方式,如存储配置数据,将参数传递给 cmdlet,并在脚本中存储数据。

要了解 PowerShell 哈希表的工作原理,首先需要创建一个如下所示的哈希表:

1. 打开 PowerShell 会话,并运行以下命令,该命令不会生成输出,但声明一个名为 name 的变量,用于引用空 hashtable。

如下所示,与 PowerShell 中的数组类似,hashtable 使用 @ 符号进行定义。

$name = @{}

2. 接下来,运行以下命令验证 name 变量的类型(GetType())。

$name.GetType()

如下所示,name 变量的类型是 Hashtable。此信息确认您的 hashtable 已成功创建。

Verifying the newly-created hashtable

3. 在验证了您的 hashtable 后,运行以下代码检查 hashtable 是否为空。

下面的代码确定 Count 属性是否等于 (-eq) 0,并打印相应的消息。

# 比较 Count 属性值是否等于 0
if ($name.Count -eq 0) {
	# 如果是,则打印下面的消息。
  Write-Output "The hashtable is empty."
} else {
	# 否则,打印下面的消息。
  Write-Output "The hashtable is not empty."
}

下面,您可以看到哈希表是空的,因为您刚刚创建它,并且其中没有定义键值对。

Checking if the hashtable is empty or not

向 PowerShell 哈希表添加项目

您刚刚创建了一个几乎空的 PowerShell 哈希表,只有在添加项目时才能发挥其作用。如何添加呢?通过向哈希表添加键值对。

与数组类似,但 PowerShell 哈希表使用键(可以是任何数据类型)而不是整数作为索引来标识值。这个特性允许快速插入、检索和删除哈希表中的项目,因为键可以快速定位相应的值。

以下是向 PowerShell 哈希表添加键值对的语法,其中:

  • $hashtable – 哈希表的名称。
  • $key – 键的名称,不区分大小写。例如,“FirstName” 和 “firstname” 在哈希表中被视为相同的键
  • $value – 与键关联的值。
$hashtable[$key] = $value

运行以下代码,虽然不会在控制台上产生输出,但会声明键值对并将它们添加到您的哈希表($name)中。

在哈希表中,键使您能够执行哈希函数,该函数将键映射到哈希表内部数据结构的特定位置。

? 哈希表的值可以是任何类型,如数字、字符串、数组、对象和其他数据类型。

#声明键FirstName
$key = "FirstName"
#声明键的值
$value = "John"
#将项目添加到哈希表中
$name[$key] = $value

#声明键LastName
$key = "LastName"
#声明键的值
$value = "Doe"
#将项目添加到哈希表中
$name[$key] = $value

现在,重新运行下面的代码以检查你的哈希表是否为空。

if ($name.Count -eq 0) {
  Write-Output "The hashtable is empty."
} else {
  Write-Output "The hashtable is not empty."
}

如下所示,这次你将收到一条消息,说哈希表不为空。

Checking if the hashtable is empty or not

从 PowerShell 哈希表检索项

假设你确信你的哈希表不为空。你如何知道哈希表中存在哪些项?幸运的是,你也可以从哈希表中检索项。

运行下面的代码,检索并输出(Write-Output)哈希表中的所有项,每行一个键值对。

#遍历哈希表中的所有键值对
foreach ($key in $name.Keys) {
	$value = $name[$key]
  #逐行输出哈希表中的所有键值对。
	Write-Output "${key}: ${value}"
}
Retrieving items from a PowerShell hashtable

现在,运行下面的代码,检索并打印(Write-Output)哈希表中的所有项到控制台。

? 请注意,你将经常在本教程中使用以下代码。你可以通过创建一个函数来避免多次复制和粘贴相同的代码,但这超出了本教程的范围。

# 获取可用于迭代集合元素的对象。
$enumerator = $name.GetEnumerator()
foreach ($element in $enumerator) {
	# 输出包含集合中每个元素的键和值的字符串。
	Write-Output "Key: $($element.Key), Value: $($element.Value)"
}

这一次,你可以看到列出的项目中哪些是键和值的指示。

Retrieving items from a PowerShell hashtable, indicating which are the keys and value pairs

创建具有预定义值的哈希表

到目前为止,你只看过创建空哈希表的情况。但是,如果你知道在你的哈希表中总是需要某些值,你可以创建一个带有预定义值的哈希表。

具有预定义值的哈希表可以节省时间,并使你的代码更有效,因为你不需要在以后向哈希表中添加值。

? 请注意,创建哈希表不会产生输出。但别担心。在本教程中,你将在创建后验证每个哈希表。

1. 运行以下命令来创建一个哈希表($hashtable1)和三个键值对。

$hashtable1 = @{
  "Key1" = "Value1"
  "Key2" = "Value2"
  "Key3" = "Value3"
}

2. 接下来,运行以下代码来验证新的哈希表(hashtable1)是否存在。

# 获取一个可用于遍历集合元素的对象。
$enumerator = $hashtable1.GetEnumerator()
foreach ($element in $enumerator) {
  # 输出一个字符串,其中包括集合中每个元素的键和值。
	Write-Output "Key: $($element.Key), Value: $($element.Value)"
}

您将看到每个键值对的值按预期打印在屏幕上。此输出确认了预定义值存储在哈希表中的适当位置。

Verifying that hashtable was created successfully with predefined values

3. 现在,运行下面的代码使用循环(或数组)创建一个具有预定义值的哈希表($hashtable2)。

$keys = "Key1", "Key2", "Key3"
$values = "Value1", "Value2", "Value3"
$hashtable2 = @{}
for ($i = 0; $i -lt $keys.Count; $i++) {
  $hashtable2[$keys[$i]] = $values[$i]
}

4. 最后,运行下面的代码验证新哈希表(hashtable2)已成功创建。

# 获取一个可用于遍历集合元素的对象。
$enumerator = $hashtable2.GetEnumerator()
foreach ($element in $enumerator) {
	# 输出一个字符串,其中包括集合中每个元素的键和值。
	Write-Output "Key: $($element.Key), Value: $($element.Value)"
}

下面的输出确认了使用循环创建具有预定义值的哈希表的方法有效。但由于项目是随机列出的,请跳转到以下部分进行修复。

Verifying the new hashtable was created successfully

在哈希表中创建项目的有序列表

默认情况下,哈希表中的项目以无特定顺序存储。但如果您需要有序列表怎么办?您也可以在哈希表中创建一个有序列表以按特定顺序排列数据。

要在哈希表中创建一个项目的有序列表,请使用[ordered]属性,如下所示:

1. 运行以下代码以创建一个[ordered]哈希表项目列表($hashtable3)。

$hashtable3 = [ordered]@{
"Key1" = "Value3"
"Key2" = "Value2"
"Key3" = "Value1"
}

2. 接下来,运行以下代码验证已成功创建哈希表的有序列表。

# 获取可用于遍历集合元素的对象。
$enumerator = $hashtable3.GetEnumerator()
foreach ($element in $enumerator) {
	# 输出一个字符串,其中包含集合中每个元素的键和值。
	Write-Output "Key: $($element.Key), Value: $($element.Value)"
}

如下所示,列出的项目保持在创建哈希表时定义的顺序中。

使用有序哈希表的一些可能好处包括但不限于以下内容:

Benefits Description
Easier to read and debug The elements are displayed in a predictable order, which can be especially useful if you work with many elements of a large hashtable.
Improved performance An ordered hashtable can be more efficient when accessing elements frequently in a specific order.
Verifying that the ordered list of hashtables has been created

3. 最后,调用有序哈希表($hashtable3)以进一步确认您仍将获得有序项目列表。

$hashtable3

下面的输出确认,无论以何种方式访问哈希表,您仍将获得有序项目列表。

Verifying the list of items is still in an ordered format

更新哈希表中的现有项目

数据不断变化,如果您有现有的哈希表,则更新它们是一项关键任务。例如,您正在使用哈希表存储配置值。如果是这样,如果配置更改,您可能需要更新键的值。

要更新PowerShell哈希表,可以使用=赋值运算符,如下所示:

1. 运行下面的命令,该命令不提供输出,但将$hashtable3Key2的键值更新为NewValue2

$hashtable3["Key2"] = "NewValue2"

下一步,运行以下命令以在哈希表(`$hashtable3`)中添加新的键值对(`Key4 = NewValue4`)。

添加新的键值对不会像更新哈希表中的现有列表那样产生输出,但您将在以下步骤中验证更改。

$hashtable3.Add("Key4", "NewValue4")

3. 运行以下代码以验证哈希表(`$hashtable3`)中键的值是否已更新。

# 获取可用于迭代集合元素的对象。
$enumerator = $hashtable3.GetEnumerator()
foreach ($element in $enumerator) {
	# 输出包含集合中每个元素的键和值的字符串。
	Write-Output "Key: $($element.Key), Value: $($element.Value)"
}
Verifying the key values have been updated

? 在PowerShell中,哈希表中的每个键必须是唯一的。如果尝试添加已在哈希表中的键值对,将会收到如下所示的错误。要避免收到此错误,请跳转到以下步骤。

Adding a key that already exists

4. 现在,运行以下代码,使用Contains()方法检查您尝试添加的键是否已存在于哈希表中,然后再添加键值对。

# 定义变量以保存新键
$newkey="Key5"
# 检查 $newkey 是否已存在于哈希表中。
if (-not $hashtable3.Contains($newkey)) {
	# 如果不存在,则添加新的键值对。
	$hashtable3.Add($newkey, "NewValue5")
	Write-Output "The new key '$newkey' has been added to the hashtable."
} else {
	# 如果键已存在,则打印一条消息。
	Write-Output "The key '$newkey' already exists."
}

如果新键不存在,您将收到下面的消息,表示新键已添加到哈希表中。

Checking if a key exists before adding it to the hashtable

否则,如下所示,如果您尝试的键已存在,您将收到一条消息。

Adding a key that already exists

5. 最后,重新运行以下代码以检索哈希表中的所有项($hashtable3)。

# 获取可用于迭代集合元素的对象。
$enumerator = $hashtable3.GetEnumerator()
foreach ($element in $enumerator) {
	# 输出一个包含集合中每个元素的键和值的字符串。
	Write-Output "Key: $($element.Key), Value: $($element.Value)"
}

下面,您可以看到新添加的键(Key5)以及到目前为止添加到哈希表中的其他项目。

Checking all items listed in a hashtable

从哈希表中删除项目

哈希表中有太多项目,尤其是不必要的项目,可能只会导致混乱。如果不再相关或不再需要的项目,从您的哈希表中删除它们将为您提供帮助。

假设您的哈希表包含用户及其信息的列表。如果是这样,请从哈希表中删除不再活跃的用户。

运行以下代码以从您的哈希表($hashtable3)中删除特定项(Key1)。

$key = "Key5"
if ($hashtable3.Contains($key)) {
  $hashtable3.Remove($key)
  Write-Output "The key-value pair with the key '$key' was removed from the hashtable."
} else {
  Write-Output "The key-value pair with the key '$key' was not found in the hashtable."
}

下面,输出会打印一条消息,表明已删除该键。但如果键不存在,则会收到一条消息,指出未找到该键。

Removing items from a hashtable

现在,运行以下代码来检查哈希表中的所有项,并验证项目是否已成功删除。

# 获取可用于迭代集合元素的对象。
$enumerator = $hashtable3.GetEnumerator()
foreach ($element in $enumerator) {
	# 输出一个包含集合中每个元素的键和值的字符串。
	Write-Output "Key: $($element.Key), Value: $($element.Value)"
}

以下,您可以验证您的哈希表中不再存在键为’Key5’的键值对。

Verifying item deletion is successful

结论

使用键值对结构和快速访问,PowerShell哈希表非常适合在各种场景中管理大量数据。在本教程中,您学习了如何创建、添加、更新和删除哈希表中的项目。所有这些都使您掌握了在脚本中有效使用哈希表的技能。

为什么不将您新获得的技能提升到更高水平呢?考虑将哈希表纳入您的脚本中,用于执行更高级的任务,例如数据操作和转换。或者尝试将哈希表与PowerShell中的其他数据结构(如数组和对象)相结合,以解决更复杂的问题呢?

Source:
https://adamtheautomator.com/powershell-hashtable/