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

[玩转系统] 使用 PowerShell ArrayList 和数组构建更好的脚本

作者:精品下载站 日期:2024-12-14 20:52:25 浏览:13 分类:玩电脑

使用 PowerShell ArrayList 和数组构建更好的脚本


通常,在编写 PowerShell 脚本时,您需要一种方法来存储一组项目。实现此目的的一种常见方法是使用数组或称为 ArrayList 的特定类型。但数组到底是什么?数组是一种数据结构,旨在存储项目的集合。这可以包括相同和不同类型的项目。

数组用于许多不同的编程语言,PowerShell 也不例外。创建、操作和优化数组的方法有很多种。在本文中,您将了解 ArrayList、数组和集合,以及通过 PowerShell 应用它们时的一些最佳实践。

先决条件/要求

由于您只使用 PowerShell 语言本身,因此没有环境先决条件。您只需要拥有一台带有 PowerShell 的 Windows PC。进一步来说:

  • Windows PowerShell 3 或更高版本
  • .NET Framework 4.5 或更高版本

想要更多这样的提示吗?查看我的个人 PowerShell 博客:https://nkasco.com/FriendsOfATA

使用 PowerShell 创建数组

使用 PowerShell 创建数组有多种不同的方法。假设您有一个需要以某种方式处理的名称列表,如下所示。

John
Susie
Jim
Johnny
Carrie

通过逗号分隔的元素构建数组

创建数组的最基本方法是简单地将已知输入(以逗号分隔)分配给变量,如下所示。

$BasicArray = "John", "Susie", "Jim", "Johnny", "Carrie"

如果您运行 PowerShell 中所有对象上可用的 GetType() 方法,您将看到您已成功创建一个数组,如下所示的 BaseType 属性所示。

PS51> $BasicArray.GetType()

IsPublic IsSerial Name                                     BaseType                                                    
-------- -------- ----                                     --------                                                    
True     True     Object[]                                 System.Array

使用子表达式运算符

您还可以通过子表达式运算符在 PowerShell 中创建数组。当您不知道将向数组添加多少项时,通常会使用此概念。创建时结果可以包含零个或多个项目。

请注意,下面创建了一个名为 $MyArray 的数组,其中包含零个元素。

#Create an empty array with the sub-expression operator
PS51> $MyArray = @()
PS51> $MyArray.count
0

使用范围运算符

数组不仅仅用于存储如上所示的字符串。您还可以使用其他对象类型(例如整数)创建数组。

如果您需要按顺序排列的整数数组,可以采用快捷方式并使用 range .. 运算符。下面您可以看到用一行代码创建了一个包含整数 2 到 5 的数组。

PS51> $NumberedArray = 2..5
PS51> $NumberedArray
2
3
4
5

创建 PowerShell ArrayList 集合

使用 PowerShell ArrayList 也是一种使用 PowerShell 存储项目列表的方法。 ArrayList 类是 .NET 中 System.Collections 命名空间的一部分。通过创建这种类型的新对象,您可以将对象存储在 ArrayList 中。

在下面您可以看到,您需要使用 New-Object cmdlet 或通过将标准数组转换为 ArrayList 对象来显式创建 ArrayList 对象。

请注意,在本例中,BaseType 是一个对象,而上面的示例具有数组的 BaseType,它表现出从 Object 类的继承。最终,PowerShell 提供对 .NET 类型系统的访问。

PS51> $MyArrayList = New-Object -TypeName "System.Collections.ArrayList"
# Casting an array as an ArrayList is also a viable option
PS51> $MyArrayList = [System.Collections.ArrayList]@()
PS51> $MyArrayList.GetType()

IsPublic IsSerial Name                                     BaseType                                                    
-------- -------- ----                                     --------                                                    
True     True     ArrayList                                System.Object

将项目添加到数组

创建数组时,您可以在创建时定义所有元素,也可以临时添加它们。

要将元素添加到现有集合,可以使用 += 运算符或 Add 方法。但要知道它们的运作方式存在重大差异。

当您使用 @() 创建标准数组时,您将使用 += 运算符,但要将元素添加到 ArrayList,您将使用 Add方法。这些方法的不同之处在于,+= 运算符实际上销毁现有数组并使用新项目创建一个新数组。

为了进行演示,您将在下面看到,您可以引用数组或 ArrayList 的 IsFixedSize 属性来了解哪些是不可变的,哪些不是。

PS51> $BasicArray.IsFixedSize
True

PS51> $MyArrayList.IsFixedSize
False

由于基本数组是固定大小的集合,因此无法修改它。

尝试对固定大小的数组使用 Add() 方法将由于固定大小而导致错误。您可以在下面看到一些示例,在这些示例中您可以成功地将项目添加到数组中。

#Does NOT work
$BasicArray.Add("Nate")

#Works
$BasicArray += "Nate"
$MyArrayList.Add("Nate")
$MyArrayList += "Nate"

从数组中删除项目

现在您已经更好地了解了如何向数组添加项目,接下来我们将介绍几种从数组中删除项目的方法。

由于基本数组是固定的,因此您无法从中删除项目。相反,您必须创建一个全新的数组。例如,您可以通过创建仅与您想要包含的元素匹配的条件语句来从数组中删除单个元素。一个例子如下所示。

$NewBasicArray = $BasicArray -ne "Nate"

由于 ArrayList 不固定,您可以使用 Remove() 方法从中删除元素。在这种情况下,如果您打算频繁添加/删除项目,那么使用 ArrayList 可能会让您受益。

$MyArrayList.Remove("Nate")

从 Array 或 ArrayList 中检索特定项目

要从数组或 ArrayList 中检索特定项目,您可以使用许多不同的方法。与 PowerShell 中的其他对象非常相似,您只需调用该对象即可访问数组的所有元素。

PS51> $BasicArray
John
Susie
Jim
Johnny
Carrie

也许您只需要检索第一个元素,数组的原点始终为 0,表示数组的第一个元素。要检索数组的第一个元素,请在括号中指定索引号,如下所示。

PS51> $BasicArray[0]
John

相反,您还可以使用破折号(负指示符)来向后引用索引,以调用数组中最后 X 个元素。查找数组中最后一个元素的常见方法是使用 -1 ,如下所示。

PS51> $BasicArray[-1]
Carrie

您在上面了解的范围运算符也可用于通过遵循调用元素的相同方法来检索数组的对象。假设您想要检索 $BasicArray 数组中的前四个名称。

您可以在下面看到,您可以指定索引 0-3 的范围,这将返回前四个元素。

PS51> $BasicArray[0..3]
John
Susie
Jim
Johnny

使用 PowerShell 优化数组

既然您已经了解了如何创建和操作数组,那么您应该使用哪一个呢?为了回答这个问题,让我们通过 Measure-Command cmdlet 来看几个示例。使用 Measure-Command cmdlet,您将更好地了解命令在管道中传递时处理元素所需的时间。

一般来说,如果您有一小部分对象,您可能不会注意到操作数组的方式有太大差异。但是,如果您有大量对象,那么了解差异以实现最佳结果就很重要。

让我们应用您在上一节中刚刚学到的有关 += 与使用 Add() 方法与 50,000 个项目的循环之间的区别的知识。

首先,创建一个空数组和一个空 ArrayList,如下所示。

PS51> $MyArray = @()
PS51> $MyArrayList = [System.Collections.ArrayList]@()

接下来,使用范围运算符和 foreach 循环在每个集合中填充 50,000 个元素,如下所示。

@(0..50000).foreach({$MyArray += $_})
@(0..50000).foreach({$MyArrayList.Add($_)})

最后,将命令包装在表达式中,并将该表达式传递给 Measure-Command cmdlet。通过使用 Measure-Command 执行表达式,您可以看到每个进程实际执行所需的时间。

请记住,正如您之前所了解的,+= 实际上创建了一个新数组,而不是附加到固定数组。

PS51> Measure-Command -Expression {@(0..50000).foreach({$MyArray += $_})}
Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 59
Milliseconds      : 58
Ticks             : 590585963
TotalDays         : 0.000683548568287037
TotalHours        : 0.0164051656388889
TotalMinutes      : 0.984309938333333
TotalSeconds      : 59.0585963
TotalMilliseconds : 59058.5963

PS51> Measure-Command -Expression {@(0..50000).foreach({$MyArrayList.Add($_)})}
Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 0
Milliseconds      : 139
Ticks             : 1399989
TotalDays         : 1.62035763888889E-06
TotalHours        : 3.88885833333333E-05
TotalMinutes      : 0.002333315
TotalSeconds      : 0.1399989
TotalMilliseconds : 139.9989

结果?近 60 秒 vs 139 毫秒!

正如您所看到的,对于大型集合来说,使用 ArrayList 比使用固定大小的数组要快得多。

虽然这是一个基本示例,但它强调了理解代码在处理过程中正在做什么的重要性。如果没有正确理解,可能会导致糟糕的用户体验。

如果您有任何现有脚本可以从使用 ArrayList 而不是数组中受益,那么这将提供一个绝佳的机会来实现一夜之间的改进!

进一步阅读

  • 比较数组与 PowerShell
  • 如何在 PowerShell (MCPmag) 中创建数组以提高性能

想要更多这样的提示吗?请查看我的个人 PowerShell 博客:https://nkasco.com/FriendsOfATA。

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

取消回复欢迎 发表评论:

关灯