当前位置:网站首页 > 更多 > 玩电脑 > 正文

[玩转系统] 关于哈希表

作者:精品下载站 日期:2024-12-14 02:22:23 浏览:15 分类:玩电脑

关于哈希表


简短描述

描述如何在 PowerShell 中创建、使用哈希表和对哈希表进行排序。

详细描述

哈希表,也称为字典或关联数组,是一种存储一个或多个键值对的紧凑数据结构。例如,哈希表可能包含一系列 IP 地址和计算机名称,其中 IP 地址是键,计算机名称是值,反之亦然。

在 PowerShell 中,每个哈希表都是一个 Hashtable [System.Collections.Hashtable] 对象。您可以在 PowerShell 中使用 Hashtable 对象的属性和方法。

从 PowerShell 3.0 开始,您可以使用 [ordered] 属性在 PowerShell 中创建 [System.Collections.Specialized.OrderedDictionary] 对象。

有序字典与哈希表的不同之处在于,键始终按照列出它们的顺序出现。哈希表中键的顺序不确定。

哈希表中的键和值也是 .NET 对象。它们通常是字符串或整数,但它们可以具有任何对象类型。您还可以创建嵌套哈希表,其中键的值是另一个哈希表。

哈希表经常使用,因为它们可以有效地查找和检索数据。您可以使用哈希表来存储列表并在 PowerShell 中创建计算属性。而且,PowerShell 有一个 cmdlet ConvertFrom-StringData,可将字符串转换为哈希表。

句法

哈希表的语法如下:

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

有序字典的语法如下:

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

PowerShell 3.0 中引入了 [ordered] 类型加速器。

创建哈希表

要创建哈希表,请遵循以下准则:

  • 哈希表以 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)"
}

此示例使用 GetEnumeratorForEach 方法来迭代每个键值对。

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

添加和删除键和值

要将键和值添加到哈希表,请使用以下命令格式。

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

例如,要将值为“Now”的“Time”键添加到哈希表中,请使用以下语句格式。

$hash["Time"] = "Now"

您还可以使用 System.Collections.Hashtable 对象的 Add 方法将键和值添加到哈希表中。 Add 方法具有以下语法:

Add(Key, Value)

例如,要将值为 NowTime 键添加到哈希表中,请使用以下语句格式。

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

并且,您可以使用加法运算符 (+) 将键和值添加到哈希表,以将哈希表添加到现有哈希表。例如,以下语句将值为 NowTime 键添加到 $hash 变量中的哈希表中。

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

您还可以添加存储在变量中的值。

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

$hash.Add($t, $now)

您不能使用减法运算符从哈希表中删除键值对,但可以使用 Hashtable 对象的Remove 方法。 Remove 方法将键作为其值。

Remove 方法具有以下语法:

Remove(Key)

例如,要从 $hash 变量值中的哈希表中删除 Time=Now 键值对,请键入:

$hash.Remove("Time")

您可以在 PowerShell 中使用 Hashtable 对象的所有属性和方法,包括 ContainsClearCloneCopyTo.有关 Hashtable 对象的详细信息,请参阅 System.Collections.Hashtable。

哈希表中的对象类型

哈希表中的键和值可以具有任何 .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 变量中的哈希表中。键是代表 WinRM 服务的 Service 对象,值是服务的当前状态。

$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

哈希表中的键和值也可以是哈希表对象。以下语句将键值对添加到 $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 cmdlet 对枚举值进行排序以供显示。

例如,以下命令枚举 $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 cmdlet 将字符串或键值对的此处字符串转换为哈希表。您可以在脚本的数据部分中安全地使用 ConvertFrom-StringData cmdlet,并且可以将其与 Import-LocalizedData cmdlet 结合使用,以在用户目录中显示用户消息。当前用户的界面 (UI) 文化。

当哈希表中的值包含引号时,Here-strings 特别有用。有关此处字符串的更多信息,请参阅 about_Quoting_Rules。

以下示例展示了如何创建上一示例中用户消息的此处字符串,以及如何使用 ConvertFrom-StringData 将它们从字符串转换为哈希表。

以下命令创建键值对的此处字符串,然后将其保存在 $string 变量中。

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

此命令使用 ConvertFrom-StringData cmdlet 将此处字符串转换为哈希表。

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_引用_规则
  • about_Script_国际化
  • Import-LocalizedData
  • ConvertFrom-StringData
  • System.Collections.Hashtable

您需要 登录账户 后才能发表评论

取消回复欢迎 发表评论:

关灯