关于数组

您所在的位置:网站首页 批量定义数组 关于数组

关于数组

2024-03-09 11:20| 来源: 网络整理| 查看: 265

about_Arrays 项目 10/06/2023 简短说明

介绍数组,这些数组是用于存储项集合的数据结构。

长说明

数组是一种数据结构,旨在存储项集合。 这些项可以是同一类型或不同类型的。

从 Windows PowerShell 3.0 开始,零个或一个对象的集合具有数组的某些属性。

创建和初始化数组

若要创建和初始化数组,请将多个值分配给变量。 数组中存储的值用逗号分隔,并用赋值运算符(=)分隔变量名。

例如,若要创建一个名为 $A 的数组,其中包含 22、5、10、8、12、9 和 80 的 7 个数值(整数)值,请键入:

$A = 22,5,10,8,12,9,80

逗号还可用于通过在单个项之前放置逗号来初始化单个项数组。

例如,若要创建一个名为 $B 的单个项数组,该数组包含 7 的单个值,请键入:

$B = ,7

还可以使用范围运算符(..)创建和初始化数组。 以下示例创建一个数组,其中包含值 5 到 8。

$C = 5..8

因此,$C 包含四个值:5、6、7 和 8。

如果未指定数据类型,PowerShell 将每个数组创建为对象数组(System.Object[])。 若要确定数组的数据类型,请使用 GetType() 方法。 例如:

$A.GetType()

若要创建强类型数组,即只能包含特定类型的值的数组,请将变量强制转换为数组类型,如 string[]、long[] 或 int32[]。 若要强制转换数组,请在变量名称前面加上括在括号中的数组类型。 例如:

[int32[]]$ia = 1500, 2230, 3350, 4000

因此,$ia 数组只能包含整数。

可以创建转换为 .NET 中任何受支持的类型的数组。 例如,Get-Process 检索以表示进程的对象属于 system.Diagnostics.Process 类型。 若要创建进程对象的强类型数组,请输入以下命令:

[Diagnostics.Process[]]$zz = Get-Process 数组子表达式运算符

数组子表达式运算符从其内的语句创建数组。 无论运算符内部的语句如何生成,运算符都会将其置于数组中。 即使有零个或一个对象。

数组运算符的语法如下所示:

@( ... )

可以使用数组运算符创建零个或一个对象的数组。 例如:

$a = @("Hello World") $a.Count 1 $b = @() $b.Count 0

获取对象时,数组运算符在脚本中非常有用,但不知道需要多少。 例如:

$p = @(Get-Process Notepad)

有关数组子表达式运算符的详细信息,请参阅 about_Operators。

访问和使用数组元素 读取数组

可以使用数组的变量名称来引用数组。 若要显示数组中的所有元素,请调用数组名称。 例如,$a 是数字 0 到 9 的数组:

$a 0 1 2 3 4 5 6 7 8 9

可以使用索引引用数组中的元素。 将索引号括在括号中。 索引值从 0 开始。 例如,若要显示 $a 数组中的第一个元素,请键入:

$a[0] 0

若要在 $a 数组中显示第三个元素,请键入:

$a[2] 2

可以使用索引的范围运算符检索数组的一部分。 例如,若要检索数组的第二到第五个元素,需要键入:

$a[1..4] 1 2 3 4

数组末尾的负数计数。 例如,-1 引用数组的最后一个元素。 若要按索引升序显示数组的最后三个元素,请键入:

$a = 0 .. 9 $a[-3..-1] 7 8 9

如果按降序键入负索引,输出将更改。

$a = 0 .. 9 $a[-1..-3] 9 8 7

但是,使用此表示法时要谨慎。 表示法从结束边界循环到数组的开头。

$a = 0 .. 9 $a[2..-2] 2 1 0 9 8

此外,一个常见的错误是假设 $a[0..-2] 引用数组的所有元素,最后一个元素除外。 它指数组中的第一个、最后一个和最后一个元素。

可以使用加号运算符(+)将范围与数组中的元素列表组合在一起。 例如,若要在索引位置 0、2 和 4 到 6 处显示元素,请键入:

$a = 0 .. 9 $a[0,2+4..6] 0 2 4 5 6

此外,若要列出多个范围和单个元素,可以使用加号运算符。 例如,若要列出 0 到 2、4 到 6 的元素,以及第八个位置类型的元素:

$a = 0..9 $a[+0..2+4..6+8] 0 1 2 4 5 6 8 对数组元素进行迭代

还可以使用循环构造(如 foreach、for 和 while 循环)来引用数组中的元素。 例如,若要使用 foreach 循环显示 $a 数组中的元素,请键入:

$a = 0..9 foreach ($element in $a) { $element } 0 1 2 3 4 5 6 7 8 9

foreach 循环访问数组,并返回数组中的每个值,直到到达数组的末尾。

在检查数组中的元素时递增计数器时,for 循环非常有用。 例如,若要使用 for 循环返回数组中的每个其他值,请键入:

$a = 0..9 for ($i = 0; $i -le ($a.length - 1); $i += 2) { $a[$i] } 0 2 4 6 8

可以使用 while 循环显示数组中的元素,直到定义的条件不再为 true。 例如,若要在数组索引小于 4 时显示 $a 数组中的元素,请键入:

$a = 0..9 $i=0 while($i -lt 4) { $a[$i] $i++ } 0 1 2 3 数组的属性 Count 或 Length 或 LongLength

若要确定数组中的项数,请使用 Length 属性或其 Count 别名。 如果数组包含的元素超过 2,147,483,647 个,则 longlength 非常有用。

$a = 0..9 $a.Count $a.Length 10 10 Rank

返回数组中的维数。 PowerShell 中的大多数数组只有一个维度。 即使你认为要生成多维数组,如以下示例所示:

$a = @( @(0,1), @("b", "c"), @(Get-Process) ) "`$a rank: $($a.Rank)" "`$a length: $($a.Length)" "`$a[2] length: $($a[2].Length)" "Process `$a[2][1]: $($a[2][1].ProcessName)"

在此示例中,你将创建一个包含其他数组的单维数组。 这也称为交错数组。 Rank 属性证明这是单维的。 若要访问交错数组中的项,索引必须位于单独的方括号([])。

$a rank: 1 $a length: 3 $a[2] length: 348 Process $a[2][1]: AcroRd32

多维数组按行主顺序存储。 以下示例演示如何创建真正的多维数组。

[string[,]]$rank2 = [string[,]]::New(3,2) $rank2.rank $rank2.Length $rank2[0,0] = 'a' $rank2[0,1] = 'b' $rank2[1,0] = 'c' $rank2[1,1] = 'd' $rank2[2,0] = 'e' $rank2[2,1] = 'f' $rank2[1,1] 2 6 d

若要访问多维数组中的项,请使用一组括号([])内的逗号(,)分隔索引。

对多维数组(如复制和串联)执行的某些操作需要平展该数组。 平展会将数组转换为不受约束类型的 1 维数组。 生成的数组按行优先顺序显示所有元素。 请考虑以下示例:

$a = "red",$true $b = (New-Object 'int[,]' 2,2) $b[0,0] = 10 $b[0,1] = 20 $b[1,0] = 30 $b[1,1] = 40 $c = $a + $b $a.GetType().Name $b.GetType().Name $c.GetType().Name $c

输出显示,$c 是一个按行主顺序、包含 $a 和 $b 项的 1 维数组。

Object[] Int32[,] Object[] red True 10 20 30 40 数组的方法 Clear

将所有元素值设置为数组元素类型的默认值。 Clear() 方法不会重置数组的大小。

在以下示例中,$a 是一组对象。

$a = 1, 2, 3 $a.Clear() $a | % { $null -eq $_ } True True True

在此示例中,显式键入 $intA 以包含整数。

[int[]] $intA = 1, 2, 3 $intA.Clear() $intA 0 0 0 ForEach()

允许循环访问数组中的所有元素,并为数组的每个元素执行给定操作。

ForEach() 方法具有多个执行不同操作的重载。

ForEach(scriptblock expression) ForEach(scriptblock expression, object[] arguments) ForEach(type convertToType) ForEach(string propertyName) ForEach(string propertyName, object[] newValue) ForEach(string methodName) ForEach(string methodName, object[] arguments) ForEach(scriptblock 表达式) ForEach(scriptblock 表达式,object[] 参数)

此方法已在 PowerShell v4 中添加。

注意

语法需要使用脚本块。 如果 scriptblock 是唯一参数,则括号是可选的。 此外,方法与左括号或大括号之间不得有空格。

以下示例演示如何使用 ForEach() 方法。 在这种情况下,意向是生成数组中元素的平方值。

$a = @(0 .. 3) $a.ForEach({ $_ * $_}) 0 1 4 9

与 ForEach-Object 的 ArgumentList 参数一样,arguments 参数允许将参数数组传递给配置为接受它们的脚本块。

有关 ArgumentList 的行为的详细信息,请参阅 about_Splatting。

ForEach(type convertToType)

ForEach() 方法可用于将元素强制转换为其他类型;以下示例演示如何将字符串日期列表转换为 [DateTime] 类型。

("1/1/2017", "2/1/2017", "3/1/2017").ForEach([datetime]) Sunday, January 1, 2017 12:00:00 AM Wednesday, February 1, 2017 12:00:00 AM Wednesday, March 1, 2017 12:00:00 AM ForEach(string propertyName) ForEach(string propertyName, object[] newValue)

ForEach() 方法还可用于检索或设置集合中每个项的属性值。

# Set all LastAccessTime properties of files to the current date. (dir 'C:\Temp').ForEach('LastAccessTime', (Get-Date)) # View the newly set LastAccessTime of all items, and find Unique entries. (dir 'C:\Temp').ForEach('LastAccessTime') | Get-Unique Wednesday, June 20, 2018 9:21:57 AM ForEach(string methodName) ForEach(string methodName, object[] 参数)

Last,ForEach() 方法可用于对集合中的每个项执行方法。

("one", "two", "three").ForEach("ToUpper") ONE TWO THREE

与 ForEach-Object 的 ArgumentList 参数一样,arguments 参数允许将值数组传递给配置为接受它们的脚本块。

注意

从 Windows PowerShell 3.0 开始,还可以使用“标量对象和集合的方法”完成集合中每个项的属性和执行方法。 可以在此处阅读有关 about_Methods 的详细信息。

Where()

允许筛选或选择数组的元素。 该脚本的计算结果必须为与零(0)、空字符串、$false 或 $null 不同的值,以便元素在 Where() 之后显示。 有关布尔评估的详细信息,请参阅 about_Booleans。

Where() 方法有一个定义。

Where(scriptblock expression[, WhereOperatorSelectionMode mode [, int numberToReturn]])

注意

语法需要使用脚本块。 如果 scriptblock 是唯一参数,则括号是可选的。 此外,方法与左括号或大括号之间不得有空格。

Expression 是筛选所需的脚本块,mode 可选参数允许其他选择功能,numberToReturn 可选参数允许限制从筛选器返回的项数。

mode 的值必须是 WhereOperatorSelectionMode 枚举值:

Default (0) - 返回所有项目 First (1) - 返回第一个项目 Last (2) - 返回最后一个项目 SkipUntil (3) - 跳过项,直到条件为 true,返回所有剩余项(包括条件为 true 的第一项) Until (4) - 返回所有项,直到条件为 true Split (5) - 返回两个元素的数组 第一个元素包含匹配项 第二个元素包含剩余的项

以下示例演示如何从数组中选择所有奇数。

(0..9).Where{ $_ % 2 } 1 3 5 7 9

此示例演示如何选择不为空的字符串。

('hi', '', 'there').Where({$_.Length}) hi there Default

Default 模式使用 Expression scriptblock 筛选项。

如果提供了 numberToReturn,则指定要返回的最大项数。

# Get the zip files in the current users profile, sorted by LastAccessTime $Zips = dir $env:userprofile -Recurse '*.zip' | Sort-Object LastAccessTime # Get the least accessed file over 100MB $Zips.Where({$_.Length -gt 100MB}, 'Default', 1)

注意

Default 模式和 First 模式都返回第一个(numberToReturn)项,并且可以互换使用。

Last $h = (Get-Date).AddHours(-1) $logs = dir 'C:\' -Recurse '*.log' | Sort-Object CreationTime # Find the last 5 log files created in the past hour $logs.Where({$_.CreationTime -gt $h}, 'Last', 5) SkipUntil

SkipUntil 模式跳过集合中的所有对象,直到对象传递脚本块表达式筛选器。 然后,它将返回所有剩余的集合项,而无需测试它们。 仅测试一个通过项。

这意味着返回的集合包含传递和未经过测试的未传递的项。

通过将值传递给 numberToReturn 参数,可以限制返回的项数。

$computers = "Server01", "Server02", "Server03", "localhost", "Server04" # Find the first available online server. $computers.Where({ Test-Connection $_ }, 'SkipUntil', 1) localhost Until

Until 模式将反转 SkipUntil 模式。 它返回集合中所有项,直到项传递脚本块表达式。 当项传递 scriptblock 表达式后,Where() 方法将停止处理项。

这意味着从 Where() 方法接收第一组未传递项。 一项通过后,其余项不会测试或返回。

通过将值传递给 numberToReturn 参数,可以限制返回的项数。

# Retrieve the first set of numbers less than or equal to 10. (1..50).Where({$_ -gt 10}, 'Until') # This would perform the same operation. (1..50).Where({$_ -le 10}) 1 2 3 4 5 6 7 8 9 10

注意

Until 和 SkipUntil 在未测试一批项目的前提下运行。

第一个传递之前Until 返回项。 第一个传递之后SkipUntil返回所有项,包括第一个传递项。

Split

Split 模式拆分或将集合项分组为两个单独的集合。 传递 scriptblock 表达式和未传递表达式的那些。

如果指定了 numberToReturn,则第一个集合包含传递项,而不是超过指定的值。

其余对象(即使是传递表达式筛选器的对象)也会在第二个集合中返回。

$running, $stopped = (Get-Service).Where({$_.Status -eq 'Running'}, 'Split') $running Status Name DisplayName ------ ---- ----------- Running Appinfo Application Information Running AudioEndpointBu... Windows Audio Endpoint Builder Running Audiosrv Windows Audio ... $stopped Status Name DisplayName ------ ---- ----------- Stopped AJRouter AllJoyn Router Service Stopped ALG Application Layer Gateway Service Stopped AppIDSvc Application Identity ...

注意

ForEach() 和 Where() 方法都是固有成员。 有关内部成员的详细信息,请参阅 about_Intrinsic_Members。

获取数组的成员

若要获取数组的属性和方法(如 Length 属性和 SetValue 方法),请使用 Get-Member cmdlet 的 InputObject 参数。

通过管道将数组传递给 Get-Member 时,PowerShell 一次发送一个项,Get-Member 返回数组中每个项的类型(忽略重复项)。

使用 InputObject 参数时,Get-Member 返回数组的成员。

例如,以下命令获取 $a 数组变量的成员。

Get-Member -InputObject $a

还可以通过在传递给 Get-Member cmdlet 的值之前键入逗号(,)来获取数组的成员。 逗号使数组成为数组中的第二项。 PowerShell 一次传递一个数组,Get-Member 返回数组的成员。 像接下来的两个示例一样。

,$a | Get-Member ,(1,2,3) | Get-Member 操作数组

可以更改数组中的元素,将元素添加到数组,并将两个数组中的值合并到第三个数组中。

若要更改数组中特定元素的值,请指定要更改的元素的数组名称和索引,然后使用赋值运算符(=)为元素指定新值。 例如,若要将 $a 数组(索引位置 1)中的第二项的值更改为 10,请键入:

$a[1] = 10

还可以使用数组的 SetValue 方法来更改值。 以下示例将 $a 数组的第二个值(索引位置 1)更改为 500:

$a.SetValue(500,1)

可以使用 += 运算符将元素添加到数组。 以下示例演示如何将元素添加到 $a 数组。

$a = @(0..4) $a += 5

注意

使用 += 运算符时,PowerShell 实际上会创建一个新数组,其中包含原始数组的值和附加值。 如果多次重复操作或数组的大小过大,则可能会导致性能问题。

从数组中删除元素并不容易,但可以创建一个新数组,该数组仅包含现有数组的选定元素。 例如,若要使用 $a 数组中的所有元素创建 $t 数组,除索引位置 2 处的值外,请键入:

$t = $a[0,1 + 3..($a.length - 1)]

若要将两个数组合并为单个数组,请使用加号运算符(+)。 以下示例创建两个数组,将它们组合在一起,然后显示生成的组合数组。

$x = 1,3 $y = 5,9 $z = $x + $y

因此,$z 数组包含 1、3、5 和 9。

若要删除数组,请将 $null 的值分配给该数组。 以下命令删除 $a 变量中的数组。

$a = $null

也可以使用 Remove-Item cmdlet,但分配 $null 值更快,尤其是对于大型数组。

零或一个的数组

从 Windows PowerShell 3.0 开始,零个或一个对象的集合具有 Count 和 Length 属性。 此外,还可以索引到一个对象的数组中。 此功能有助于避免在需要集合的命令获取少于两个项目时发生的脚本错误。

以下示例演示了此功能。

零对象 $a = $null $a.Count $a.Length 0 0 一个对象 $a = 4 $a.Count $a.Length $a[0] $a[-1] 1 1 4 4 系统索引支持。Tuple 对象

PowerShell 6.1 添加了对 Tuple 对象的索引访问的支持,类似于数组。 例如:

PS> $tuple = [Tuple]::Create(1, 'test') PS> $tuple[0] 1 PS> $tuple[1] test PS> $tuple[0..1] 1 test PS> $tuple[-1] test

与数组和其他集合对象不同,Tuple 对象在通过管道或支持对象数组的参数传递时被视为单个对象。

有关详细信息,请参阅系统Tuple。

实现 IDictionary 的 .NET 类型编制索引

对于实现泛型 IDictionary 接口的类型,PowerShell 不会调用类型的真实索引器。 相反,当给定密钥时,PowerShell 会使用 TryGetValue() 测试密钥是否存在,当密钥不存在时,它将返回 $null。

相比之下,如果使用 Item() 调用类型的 true 索引器,则当键不存在时,该方法将引发异常。

以下示例演示了差异。

PS> [Collections.Generic.Dictionary[string, int]]::new()['nosuchkey'] # No output ($null) PS> [Collections.Generic.Dictionary[string, int]]::new().Item('nosuchkey') GetValueInvocationException: Exception getting "Item": "The given key 'nosuchkey' was not present in the dictionary." 成员访问枚举

从 PowerShell 3.0 开始,使用成员访问运算符访问列表集合上不存在的成员时,PowerShell 会自动枚举集合中的项,并尝试访问每个项上的指定成员。 有关详细信息,请参阅 about_Member Access_Enumeration。

示例

以下示例创建两个新文件,并将生成的对象存储在数组变量 $files 中。 由于数组对象没有 LastWriteTime 成员,因此将为数组中的每个项返回 LastWriteTime 的值。

$files = (New-Item -Type File -Force '/temp/t1.txt'), (New-Item -Force -Type File '/temp/t2.txt') $files.LastWriteTime Friday, June 25, 2021 1:21:17 PM Friday, June 25, 2021 1:21:17 PM

通过成员访问枚举,可以从集合中的项获取值,但不能对集合中的项设置值。 例如:

$files.LastWriteTime = (Get-Date).AddDays(-1) InvalidOperation: The property 'LastWriteTime' cannot be found on this object. Verify that the property exists and can be set.

若要设置值,必须使用方法。

$files.set_LastWriteTime((Get-Date).AddDays(-1)) $files.LastWriteTime Thursday, June 24, 2021 1:23:30 PM Thursday, June 24, 2021 1:23:30 PM

set_LastWriteTime() 方法是 FileInfo 对象的隐藏成员。 以下示例演示如何查找具有隐藏set 方法的成员。

$files | Get-Member | Where-Object Definition -like '*set;*' TypeName: System.IO.FileInfo Name MemberType Definition ---- ---------- ---------- Attributes Property System.IO.FileAttributes Attributes {get;set;} CreationTime Property datetime CreationTime {get;set;} CreationTimeUtc Property datetime CreationTimeUtc {get;set;} IsReadOnly Property bool IsReadOnly {get;set;} LastAccessTime Property datetime LastAccessTime {get;set;} LastAccessTimeUtc Property datetime LastAccessTimeUtc {get;set;} LastWriteTime Property datetime LastWriteTime {get;set;} LastWriteTimeUtc Property datetime LastWriteTimeUtc {get;set;}

注意

由于为集合中的每个项执行该方法,因此在使用成员枚举调用方法时应小心。

另请参阅 about_For about_ForEach about_Hash_Tables about_Member-Access_Enumeration about_Operators about_Assignment_Operators about_While


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3