注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

我的博客

 
 
 

日志

 
 

〔TechNet译文〕与哈希表共事  

2009-11-16 14:53:10|  分类: powershell |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
在上周的Windows PowerShell提示中我们向你介绍了.NET Framework类System.Collections.ArrayList,把这个类定位为作为内建于Windows PowerShell中的数组的替代。(为什么你需要内建在Windows PowerShell中的数组类的替代?好的,有一件事,ArrayList能简单的从数组删除项目,这件事对内置的数组而言几乎是不可能的)在同样的专栏中我们承诺,本周,我们将会讨论对Windows PowerShell中使用数组而言的另外一个可选的方案:哈希表。好的,不要一直说脚本专家们不一直遵守他们的诺言。

注意:好的,技术上我们不总是遵守我们的承诺。我们只是不想被那样说罢了。

尽管哈希表这个术语对你们中的很多人来说是新名词,那么现在就是你熟悉这方面概念的好机会了;毕竟,哈希表是简单的名称-值的集合,同FileSystemObejct的Dictionary对象很相似。例如,假设你有一组美国州名及其首府的集合。每一个州只有一个,也仅有一个,首府(例如,华盛顿的州首府是奥林匹亚),给出的城市只能是一个州的首府。如果你想要记录并使用这个信息,你能构造一个二维数组。或者你能采取更简单的方法,创建哈希表。

注意:是的,我们知道:我们没有真正的复习键-值对的内容,是么?但不要紧。Dictionary对象的解释能在Microsoft Windows 2000 Scripting Guide中找到,同样也适用于Windows PowerShell的哈希表。

谈论的够多了,让我们看看一些代码。假设你真的想要一个包含美国州及它们首府的列表的一个哈希表;你打算怎么样创建呢?好的,这里有一个方法:
  1. $states = @{"Washington" = "Olympia"; "Oregon" = "Salem"; California = "Sacramento"}
复制代码
姑且承认第一眼看上去有点难以理解;然而幸运的是,这不像看上去的那样复杂。我们在这所做的是将三对键-值对赋值给名为$states的哈希表。如你所见,创建哈希表的语法包括一个@标记后跟一对花括号。

注意: @只在英文中被称为at标记;在其它语言中,它有一些很酷的称法,像maggot, monkey’s tail, and pickled herrin。

那么在花括号内发生了什么呢?好的,这是我们指定键-值对的地方,使用这样的语法key = value;例如:"Washington" = "Olympia"。注意我们使用分号分隔每一对独立的键-值;所以使用语法就是"Washington" = "Olympia"; "Oregon" = "Salem"。

那么当我们运行我们的哈希表命令之后$states变量会等于什么呢?为什么这么问,当然,是以下内容:
  1. ame                           Value

  2. ----                            -----

  3. California                     Sacramento

  4. Washington                     Olympia

  5. Oregon                         Salem
复制代码
这很好 ,除了一件事:我们的哈希表离完整还很远。(毕竟,我们只列出来三个州,而事实上……呃……美国不止三个州)那么你如何向已存在的哈希表内添加新的键-值对呢?好的,我们不知道你怎么样,但是下面是脚本专家如何实现的:
  1. $states.Add("Alaska", "Fairbanks")
复制代码
注意: 是的,是的,我们知道:费尔班克斯不是阿拉斯加的首府。我们等会会说明的。

不用多说,没有比这更有想象力的事了:我们简单的调用Add方法,并转递给这个方法两个参数:新键("Alaska")及新值("Fairbanks")。现在我们看下$states的值:
  1. Name                           Value

  2. ----                             -----

  3. California                     Sacramento

  4. Alaska                         Fairbanks

  5. Washington                     Olympia

  6. Oregon                         Salem
复制代码
顺便说一句,这是一个好的观察点:我们永远不知道新条目将会确切的出现在哈希表的哪个位置。在这种情况下,例如,我们的新条目不晓得什么缘故成为有4个项目表中的第二个。但是这没什么;在我们走之前我们会向你展示怎么样测试已存在的键或值而不用顾及他们在哈希表中的位置。然后,因为遇到这种糟糕的事,我们也将会向你展示如何对表进行排序。

不过要紧的是,潮水般的电子邮件和电话使得事情变得很清楚,阿拉斯加的州首府所在地毕竟不是费尔班克斯,而是朱诺。然而不幸的是,我们已经向我们的哈希表添加了这个错误的键-值。现在我们打算怎么办?

好的,一件我们能做的事情是简单的移除得罪人的项目。想要删除Alaska键-值对?好的,除了Remove方法外你还能用什么?
  1. $states.Remove("Alaska")
复制代码
为了安全起见,我们再看下$states的值:
  1. Name                           Value

  2. ----                           -----

  3. California                     Sacramento

  4. Washington                     Olympia

  5. Oregon                         Salem
复制代码
好多了,不是么?

另外,我们也能使用Set_Item方法来改变赋值给Alaska的值:
  1. $states.Set_Item("Alaska", "Juneau")
复制代码
运行这这个命令,然后看下$states的值,应当和以下的输出相同:
  1. Name                           Value

  2. ----                             -----

  3. California                     Sacramento

  4. Alaska                         Juneau

  5. Washington                     Olympia

  6. Oregon                         Salem
复制代码
顺便说一句,既然有Set_Item方法那么自然有名为Get_Item的方法。这方法使得我们能够提取和哈希表中指定项目相关的值。不确定俄勒冈的首府是哪座城市?那么运行以下命令,你自己来寻找答案吧:
  1. $states.Get_Item("Oregon")
复制代码
现在假设,俄勒冈州没有出现在你的哈希表内,那么当你运行先前命令的时候会发生什么?好的,实际上,不会发生什么:你不会得到任何类型的返回值,也不会得到错误消息。这确实是一个问题:在看上去什么都发生的情况下去找出到底发生了什么是需要一点技巧的。

幸运的是,你能够使用ContainsKey及ContainsValue方法来寻找哈希表内的项目。想要知道一个名为Oregon的项目是否存在于你的哈希表内?那么就调用ContainsKey方法吧,像这样:
  1. $states.ContainsKey("Oregon")
复制代码
这个方法返回True如果在哈希表内找到名为Oregon的项,如果没有找到则返回False。同样的,你能通过使用ContainsValue方法寻找在哈希表内是否包含指定的值:
  1. $states.ContainsValue("Salem")
复制代码
注意: 如果仅想知道在哈希表内有多少个像的话,你能简单回显Count属性的值:$states.Count

最后,但是却是重要的,让我们讨论对哈希表进行排序。这需要点小技巧,下面的命令将不会工作:
  1. $states | Sort-Object
复制代码
为什么不能工作呢?好的,在先前的命令中哈希表是作为单独的对象被发送的,因此对Sort-Object cmdlet而言就没什么东西能排序了。如果我们想要对哈希表进行排序我们需要使用GetEnumerator方法,这将有效的穿过管道符发送哈希表内的每一个条目,使每个条目作为独立的对象:
  1. $states.GetEnumerator() | Sort-Object Name
复制代码
因此我们将得到以下类似的输出:
  1. Name                           Value

  2. ----                              -----

  3. Alaska                          Juneau

  4. California                     Sacramento

  5. Oregon                         Salem

  6. Washington                     Olympia
复制代码
这里有一个相似的命令,除了这个是用来对哈希表的值进行降序排序的(仅仅因为我们想要秀一下):
  1. $states.GetEnumerator() | Sort-Object Value -descending
复制代码
下面是该命令得到的输出:
  1. Name                           Value

  2. ----                             -----

  3. Oregon                         Salem

  4. California                     Sacramento

  5. Washington                     Olympia

  6. Alaska                         Juneau
复制代码



PowerShell中的HashTable的使用

哈希表(hashtable)有时候也被称为:“关联数组”或“字典”。哈希表可以称得上是计算机科学中最重要的数据结构之一,例如:在计算机操作系统、数据库系统、编译器、加密算法等计算机底层程序中,哈希表都发挥着重要的作用。哈希表提供以近乎常数时间开销,根据数据的键(key)来索引到该键对应的值(value)。就好像使用工具书一样,我们总是通过目录中项的名称和页码,来检索我们关心的知识或信息。

在传统的Unix环境中,awk程序内置的关联数组,为数据处理提供了便捷的手段。因此掌握哈希表类型,可以使您在解决工作中的问题时候,更加得心应手。

如何声明一个哈希表对象?哈希表的创建是非常简单的,请看如下示例:

PS C:\> $hash = @{}

PS C:\> $hash.GetType().FullName

System.Collections.Hashtable

PS C:\> $hash.Count

0

示例中首先使用了“@{}”语法初始化了一个空的哈希表,并将其保存在变量$hash中。接下来验证了该对象的类型,并查看了哈希表中元素的数量,由于只是初始化了一个空哈希表,所以返回结果是0。如果在初始化时,需要添加一些键值对到哈希表的话,应该使用什么样的语法呢?我们只要在“@{”和“}”标记之间输入以分号“;”分隔的键值对即可,键值对的格式:<key> = <value>。请看如下示例:

PS C:\> $hash = @{ "Computer Name" = "AD Server";

>> "Administrator" = "Ma Tao""Spider Man";

>> "OS" = "Windows 2008";

>> "Installed Date" = Get-Date;

>> "Disk Size" = 5000GB

>> }

>>

PS C:\> $hash

Name                           Value

----                           -----

OS                             Windows 2008

Disk Size                      5368709120000

Installed Date                 2008/7/31 23:09:57

Computer Name                  AD Server

Administrator                  {Ma Tao, Spider Man}

这是一个记录服务器信息的哈希表,哈希表的所有信息都已经可以看到。在创建哈希表的时候,键“Administrator”对应的值是一个数组的引用;类似的还有安装日期是命令Get-Date返回的对象。通过这个例子,我们可以了解到PowerShell中的哈希表可以很方便地存储各式各样的数据信息。但是我们应该如何去访问哈希表中的元素呢?在PowerShell中,有两种便捷的办法获取哈希表中存储的信息。第一种办法是类似访问对象属性的方法:

PS C:\> $hash.os

Windows 2008

PS C:\> $hash.Administrator

Ma Tao

Spider Man

PS C:\> $hash."Computer Name"

AD Server

这种方法很方便,只需要在点号后面输入键的名称即可。如果键值包含空白字符的话,可以通过使用引号来访问该键值对应的信息。如果希望能够同时索引多个键的值,这种类似访问属性的方法就无法完成了。不过PowerShell提供了另一种办法,它类似于数组访问的形式,使得我们可以同时返回哈希表中的几个元素。例如:

PS C:\> $hash["Disk Size""Installed Date"]

5368709120000

2008731 23:09:57


http://blog.chinaunix.net/u1/42924/showart_1098777.html

  评论这张
 
阅读(650)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017