[玩转系统] 关于数组你想知道的一切
作者:精品下载站 日期:2024-12-14 03:04:33 浏览:14 分类:玩电脑
关于数组你想知道的一切
数组是大多数编程语言的基本语言功能。它们是难以避免的值或对象的集合。让我们仔细看看数组以及它们所提供的一切。
笔记
本文的原始版本出现在@KevinMarquette 撰写的博客上。 PowerShell 团队感谢 Kevin 与我们分享这些内容。请查看他的博客:PowerShellExplained.com。
什么是数组?
我将从基本技术描述开始,介绍什么是数组以及大多数编程语言如何使用数组,然后再介绍 PowerShell 使用数组的其他方式。
数组是一种数据结构,充当多个项目的集合。您可以迭代数组或使用索引访问单个项目。该数组被创建为一个连续的内存块,其中每个值都紧邻另一个值存储。
我将在讨论过程中逐一讨论这些细节。
基本用法
由于数组是 PowerShell 的基本功能,因此在 PowerShell 中使用数组有一个简单的语法。
创建一个数组
可以使用@()
创建一个空数组
PS> $data = @()
PS> $data.count
0
我们可以创建一个数组并为其添加值,只需将它们放在 @()
括号中即可。
PS> $data = @('Zero','One','Two','Three')
PS> $data.count
4
PS> $data
Zero
One
Two
Three
该数组有 4 项。当我们调用 $data
变量时,我们会看到项目列表。如果它是一个字符串数组,那么我们会为每个字符串获取一行。
我们可以在多行上声明一个数组。在这种情况下,逗号是可选的,通常可以省略。
$data = @(
'Zero'
'One'
'Two'
'Three'
)
我更喜欢像这样在多行上声明我的数组。当您有多个项目时,它不仅变得更容易阅读,而且在使用源代码管理时也更容易与以前的版本进行比较。
其他语法
人们通常认为 @()
是创建数组的语法,但逗号分隔的列表在大多数情况下都有效。
$data = 'Zero','One','Two','Three'
写入输出以创建数组
一个值得一提的很酷的小技巧是,您可以使用 Write-Output
在控制台快速创建字符串。
$data = Write-Output Zero One Two Three
这很方便,因为当参数接受字符串时,您不必在字符串两边加上引号。我永远不会在脚本中这样做,但在控制台中这是公平的游戏。
访问项目
现在您已经有了一个包含项目的数组,您可能想要访问和更新这些项目。
抵消
要访问单个项目,我们使用方括号 []
以及从 0 开始的偏移值。这就是我们获取数组中第一项的方法:
PS> $data = 'Zero','One','Two','Three'
PS> $data[0]
Zero
我们在这里使用零的原因是因为第一个项目位于列表的开头,因此我们使用 0 个项目的偏移量来获取它。要到达第二项,我们需要使用偏移量 1 来跳过第一项。
PS> $data[1]
One
这意味着最后一项位于偏移量 3 处。
PS> $data[3]
Three
指数
现在您可以明白为什么我为本示例选择了这些值。我将其引入为偏移量,因为它确实如此,但此偏移量通常称为索引。从 0
开始的索引。在本文的其余部分中,我将把偏移量称为索引。
特殊索引技巧
在大多数语言中,您只能指定一个数字作为索引,然后返回单个项目。 PowerShell 更加灵活。您可以一次使用多个索引。通过提供索引列表,我们可以选择多个项目。
PS> $data[0,2,3]
Zero
Two
Three
根据提供的索引的顺序返回项目。如果您复制一个索引,则两次都会获得该项目。
PS> $data[3,0,3]
Three
Zero
Three
我们可以使用内置的 ..
运算符指定数字序列。
PS> $data[1..3]
One
Two
Three
这也适用于相反的情况。
PS> $data[3..1]
Three
Two
One
您可以使用负索引值从末尾偏移。因此,如果您需要列表中的最后一项,可以使用 -1
。
PS> $data[-1]
Three
这里需要注意的是 ..
运算符。序列 0..-1
和 -1..0
计算结果为值 0,-1
和 -1,0
。如果您忘记了此详细信息,很容易看到 $data[0..-1]
并认为它会枚举所有项目。 $data[0..-1]
通过给出数组中的第一个和最后一个项目(以及没有其他值)。这是一个更大的例子:
PS> $a = 1,2,3,4,5,6,7,8
PS> $a[2..-1]
3
2
1
8
这与:
PS> $a[2,1,0,-1]
3
2
1
8
出界
在大多数语言中,如果您尝试访问超出数组末尾的项目的索引,您将收到某种类型的错误或异常。 PowerShell 默默地不返回任何内容。
PS> $null -eq $data[9000]
True
无法索引空数组
如果您的变量是 $null
并且您尝试像数组一样对其进行索引,则会出现 System.Management.Automation.RuntimeException
异常,并显示消息 Cannot index into一个空数组
。
PS> $empty = $null
PS> $empty[0]
Error: Cannot index into a null array.
因此,在尝试访问数组中的元素之前,请确保数组不是 $null
。
数数
数组和其他集合有一个 count 属性,可以告诉您数组中有多少项。
PS> $data.count
4
PowerShell 3.0 为大多数对象添加了计数属性。您可以有一个对象,它应该为您提供 1
计数。
PS> $date = Get-Date
PS> $date.count
1
即使 $null
也有一个 count 属性,只不过它返回 0
。
PS> $null.count
0
当我在本文后面介绍检查 $null
或空数组时,我将再次讨论这里的一些陷阱。
相差一误差
由于数组从索引 0 开始,因此会产生常见的编程错误。可以通过两种方式引入差一错误。
第一种方法是在心里认为您想要第二个项目并使用索引 2
并真正获得第三个项目。或者认为您有四个项目并且您想要最后一个项目,因此您使用计数来访问最后一个项目。
$data[ $data.count ]
PowerShell 非常乐意让您这样做,并准确地给出索引 4 处存在的项目:$null
。您应该使用我们上面了解的 $data.count - 1
或 -1
。
PS> $data[ $data.count - 1 ]
Three
您可以在此处使用 -1
索引来获取最后一个元素。
PS> $data[ -1 ]
Three
Lee Dailey 还向我指出,我们可以使用 $data.GetUpperBound(0)
来获取最大索引号。
PS> $data.GetUpperBound(0)
3
PS> $data[ $data.GetUpperBound(0) ]
Three
第二种最常见的方法是迭代列表时而不是在正确的时间停止。当我们讨论使用 for
循环时,我将重新讨论这一点。
更新项目
我们可以使用相同的索引来更新数组中的现有项目。这使我们能够直接访问更新单个项目。
$data[2] = 'dos'
$data[3] = 'tres'
如果我们尝试更新最后一个元素之后的项目,则会收到 Index was Outside of the array.
错误。
PS> $data[4] = 'four'
Index was outside the bounds of the array.
At line:1 char:1
+ $data[4] = 'four'
+ ~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (:) [], IndexOutOfRangeException
+ FullyQualifiedErrorId : System.IndexOutOfRangeException
稍后当我讨论如何使数组变得更大时我会再次讨论这一点。
迭代
在某些时候,您可能需要遍历或迭代整个列表,并对数组中的每个项目执行一些操作。
管道
数组和 PowerShell 管道是相辅相成的。这是处理这些值的最简单方法之一。当您将数组传递到管道时,数组中的每个项目都会被单独处理。
PS> $data = 'Zero','One','Two','Three'
PS> $data | ForEach-Object {"Item: [$PSItem]"}
Item: [Zero]
Item: [One]
Item: [Two]
Item: [Three]
如果您以前没有见过 $PSItem
,只需知道它与 $_
是一样的。您可以使用其中之一,因为它们都代表管道中的当前对象。
ForEach 循环
ForEach
循环适用于集合。使用语法:foreach ( in )
foreach ( $node in $data )
{
"Item: [$node]"
}
ForEach 方法
我往往会忘记这一点,但它对于简单的操作来说效果很好。 PowerShell 允许您对集合调用 .ForEach()
。
PS> $data.foreach({"Item [$PSItem]"})
Item [Zero]
Item [One]
Item [Two]
Item [Three]
.foreach()
采用一个脚本块参数。您可以删除括号并仅提供脚本块。
$data.foreach{"Item [$PSItem]"}
这是一种鲜为人知的语法,但其工作原理是一样的。此 foreach
方法是在 PowerShell 4.0 中添加的。
For循环
for
循环在大多数其他语言中都有大量使用,但在 PowerShell 中却很少见到。当您确实看到它时,通常是在遍历数组的情况下。
for ( $index = 0; $index -lt $data.count; $index++)
{
"Item: [{0}]" -f $data[$index]
}
我们要做的第一件事是将 $index
初始化为 0
。然后我们添加条件:$index
必须小于$data.count
。最后,我们指定每次循环时都必须将索引增加1
。在本例中,$index++
是 $index=$index + 1
的缩写。格式运算符 (-f
) 用于在输出字符串中插入 $data[$index]
的值。
每当您使用 for
循环时,请特别注意条件。我在这里使用了 $index -lt $data.count
。条件稍有错误很容易导致逻辑中出现相差一的错误。使用 $index -le $data.count
或 $index -lt ($data.count - 1)
是稍微错误的。这会导致您的结果处理太多或太少的项目。这是典型的差一错误。
开关回路
这是很容易被忽视的一点。如果您向 switch 语句提供一个数组,它会检查数组中的每一项。
$data = 'Zero','One','Two','Three'
switch( $data )
{
'One'
{
'Tock'
}
'Three'
{
'Tock'
}
Default
{
'Tick'
}
}
Tick
Tock
Tick
Tock
我们可以使用 switch 语句做很多很酷的事情。我还有另一篇文章专门讨论这个问题。
- 关于 switch 语句你想知道的一切
更新值
当数组是字符串或整数(值类型)的集合时,有时您可能希望在循环遍历数组中的值时更新它们。上面的大多数循环在循环中使用一个变量来保存值的副本。如果更新该变量,则数组中的原始值不会更新。
该语句的例外是 for
循环。如果您想遍历数组并更新其中的值,那么 for
循环就是您所需要的。
for ( $index = 0; $index -lt $data.count; $index++ )
{
$data[$index] = "Item: [{0}]" -f $data[$index]
}
此示例按索引获取一个值,进行一些更改,然后使用相同的索引将其分配回来。
对象数组
到目前为止,我们在数组中放置的唯一内容是值类型,但数组也可以包含对象。
$data = @(
[pscustomobject]@{FirstName='Kevin';LastName='Marquette'}
[pscustomobject]@{FirstName='John'; LastName='Doe'}
)
当您将对象集合分配给变量时,许多 cmdlet 会将对象集合作为数组返回。
$processList = Get-Process
我们已经讨论过的所有基本功能仍然适用于对象数组,但有一些细节值得指出。
访问属性
我们可以使用索引来访问集合中的单个项目,就像使用值类型一样。
PS> $data[0]
FirstName LastName
----- ----
Kevin Marquette
我们可以直接访问和更新属性。
PS> $data[0].FirstName
Kevin
PS> $data[0].FirstName = 'Jay'
PS> $data[0]
FirstName LastName
----- ----
Jay Marquette
数组属性
通常,您必须像这样枚举整个列表才能访问所有属性:
PS> $data | ForEach-Object {$_.LastName}
Marquette
Doe
或者使用 Select-Object -ExpandProperty
cmdlet。
PS> $data | Select-Object -ExpandProperty LastName
Marquette
Doe
但是 PowerShell 为我们提供了直接请求 LastName
的能力。 PowerShell 为我们枚举了所有这些并返回一个干净的列表。
PS> $data.LastName
Marquette
Doe
枚举仍然发生,但我们看不到其背后的复杂性。
地点对象过滤
这就是 Where-Object
发挥作用的地方,因此我们可以根据对象的属性从数组中过滤并选择我们想要的内容。
PS> $data | Where-Object {$_.FirstName -eq 'Kevin'}
FirstName LastName
----- ----
Kevin Marquette
我们可以编写相同的查询来获取我们正在寻找的FirstName
。
$data | Where FirstName -eq Kevin
Where()
数组有一个 Where()
方法,允许您为过滤器指定一个 scriptblock
。
$data.Where({$_.FirstName -eq 'Kevin'})
此功能是在 PowerShell 4.0 中添加的。
更新循环中的对象
对于值类型,更新数组的唯一方法是使用 for 循环,因为我们需要知道索引来替换值。我们对对象有更多选择,因为它们是引用类型。这是一个简单的例子:
foreach($person in $data)
{
$person.FirstName = 'Kevin'
}
此循环遍历 $data 数组中的每个对象。由于对象是引用类型,因此 $person
变量引用数组中完全相同的对象。因此对其属性的更新确实会更新原始属性。
您仍然无法以这种方式替换整个对象。如果您尝试将新对象分配给 $person
变量,则会将变量引用更新为不再指向数组中原始对象的其他内容。这并不像您期望的那样工作:
foreach($person in $data)
{
$person = [pscustomobject]@{
FirstName='Kevin'
LastName='Marquette'
}
}
运营商
PowerShell 中的运算符也适用于数组。其中一些的工作方式略有不同。
-join
-join
运算符是最明显的,所以让我们先看一下它。我喜欢 -join
运算符并且经常使用它。它将数组中的所有元素与您指定的字符或字符串连接起来。
PS> $data = @(1,2,3,4)
PS> $data -join '-'
1-2-3-4
PS> $data -join ','
1,2,3,4
我喜欢 -join
运算符的功能之一是它可以处理单个项目。
PS> 1 -join '-'
1
我在日志记录和详细消息中使用它。
PS> $data = @(1,2,3,4)
PS> "Data is $($data -join ',')."
Data is 1,2,3,4.
-加入$数组
这是李·戴利向我指出的一个巧妙的技巧。如果您想在没有分隔符的情况下连接所有内容,请不要这样做:
PS> $data = @(1,2,3,4)
PS> $data -join $null
1234
您可以使用 -join
将数组作为不带前缀的参数。看一下这个例子就知道我在说什么了。
PS> $data = @(1,2,3,4)
PS> -join $data
1234
- 替换和 - 分割
其他运算符(例如 -replace
和 -split
)对数组中的每个项目执行。我不能说我曾经以这种方式使用过它们,但这里有一个例子。
PS> $data = @('ATX-SQL-01','ATX-SQL-02','ATX-SQL-03')
PS> $data -replace 'ATX','LAX'
LAX-SQL-01
LAX-SQL-02
LAX-SQL-03
-contains
-contains
运算符允许您检查值数组以查看它是否包含指定值。
PS> $data = @('red','green','blue')
PS> $data -contains 'green'
True
-in
当您想要验证单个值是否与多个值之一匹配时,可以使用 -in
运算符。值位于运算符的左侧,数组位于运算符的右侧。
PS> $data = @('red','green','blue')
PS> 'green' -in $data
True
如果列表很大,这可能会变得昂贵。如果我要检查多个值,我经常使用正则表达式模式。
PS> $data = @('red','green','blue')
PS> $pattern = "^({0})$" -f ($data -join '|')
PS> $pattern
^(red|green|blue)$
PS> 'green' -match $pattern
True
-eq 和 -ne
相等和数组可能会变得复杂。当数组位于左侧时,每个项目都会进行比较。它不返回 True,而是返回匹配的对象。
PS> $data = @('red','green','blue')
PS> $data -eq 'green'
green
当您使用 -ne
运算符时,我们会得到所有不等于我们的值的值。
PS> $data = @('red','green','blue')
PS> $data -ne 'green'
red
blue
当您在 if()
语句中使用它时,返回的值为 True
值。如果没有返回值,则它是一个 False
值。接下来的两个语句的计算结果均为True
。
$data = @('red','green','blue')
if ( $data -eq 'green' )
{
'Green was found'
}
if ( $data -ne 'green' )
{
'And green was not found'
}
当我们讨论 $null
测试时,我将再次讨论这一点。
-match
-match
运算符尝试匹配集合中的每个项目。
PS> $servers = @(
'LAX-SQL-01'
'LAX-API-01'
'ATX-SQL-01'
'ATX-API-01'
)
PS> $servers -match 'SQL'
LAX-SQL-01
ATX-SQL-01
当您将 -match
与单个值一起使用时,特殊变量 $Matches
将填充匹配信息。当以这种方式处理数组时,情况并非如此。
我们可以对Select-String
采取相同的方法。
$servers | Select-String SQL
我在另一篇名为“使用正则表达式的多种方法”的文章中仔细研究了 Select-String
、-match
和 $matches
变量。
$null 或空
测试 $null
或空数组可能很棘手。以下是数组的常见陷阱。
乍一看,这个说法应该可行。
if ( $array -eq $null)
{
'Array is $null'
}
但我刚刚回顾了 -eq
如何检查数组中的每个项目。因此,我们可以拥有一个由多个项目组成的数组,这些项目具有单个 $null 值,并且其计算结果为 $true
$array = @('one',$null,'three')
if ( $array -eq $null)
{
'I think Array is $null, but I would be wrong'
}
这就是为什么最佳实践是将 $null
放置在运算符的左侧。这使得这种情况不再是问题。
if ( $null -eq $array )
{
'Array actually is $null'
}
$null
数组与空数组不同。如果您知道有一个数组,请检查其中对象的数量。如果数组为 $null
,则计数为 0
。
if ( $array.count -gt 0 )
{
"Array isn't empty"
}
这里还有一个陷阱需要提防。即使您只有一个对象,也可以使用 count
,除非该对象是 PSCustomObject
。这是 PowerShell 6.1 中修复的一个错误。这是个好消息,但很多人仍在使用 5.1,需要留意。
PS> $object = [PSCustomObject]@{Name='TestObject'}
PS> $object.count
$null
如果您仍在使用 PowerShell 5.1,则可以在检查计数之前将对象包装在数组中以获得准确的计数。
if ( @($array).count -gt 0 )
{
"Array isn't empty"
}
为了确保安全,请检查 $null
,然后检查计数。
if ( $null -ne $array -and @($array).count -gt 0 )
{
"Array isn't empty"
}
全部-eq
我最近在 Reddit 上看到有人询问如何验证数组中的每个值是否与给定值匹配。 Reddit 用户 u/bis
有一个聪明的解决方案,可以检查任何不正确的值,然后翻转结果。
$results = Test-Something
if ( -not ( $results -ne 'Passed') )
{
'All results a Passed'
}
添加到数组
此时,您开始想知道如何向数组添加项目。快速的回答是你不能。数组在内存中是固定大小的。如果您需要增长它或向其中添加单个项目,那么您需要创建一个新数组并从旧数组复制所有值。这听起来工作量很大,但是,PowerShell 隐藏了创建新数组的复杂性。 PowerShell 实现了数组的加法运算符 (+
)。
笔记
PowerShell 不实现减法运算。如果您想要数组的灵活替代方案,则需要使用通用 List
对象。
数组加法
我们可以使用数组的加法运算符来创建一个新数组。所以给定这两个数组:
$first = @(
'Zero'
'One'
)
$second = @(
'Two'
'Three'
)
我们可以将它们加在一起得到一个新的数组。
PS> $first + $second
Zero
One
Two
Three
加等于+=
我们可以就地创建一个新数组并向其中添加一个项目,如下所示:
$data = @(
'Zero'
'One'
'Two'
'Three'
)
$data += 'four'
请记住,每次使用 +=
时,您都会复制并创建一个新数组。对于小型数据集来说这不是问题,但它的扩展性非常差。
管道分配
您可以将任何管道的结果分配给变量。如果它包含多个项目,则它是一个数组。
$array = 1..5 | ForEach-Object {
"ATX-SQL-$PSItem"
}
通常,当我们想到使用管道时,我们会想到典型的 PowerShell 单行代码。我们可以通过 foreach() 语句和其他循环来利用管道。因此,我们可以将项目放入管道中,而不是在循环中将项目添加到数组中。
$array = foreach ( $node in (1..5))
{
"ATX-SQL-$node"
}
数组类型
默认情况下,PowerShell 中的数组创建为 [PSObject[]]
类型。这允许它包含任何类型的对象或值。这是可行的,因为所有内容都是从 PSObject
类型继承的。
强类型数组
您可以使用类似的语法创建任何类型的数组。创建强类型数组时,它只能包含指定类型的值或对象。
PS> [int[]] $numbers = 1,2,3
PS> [int[]] $numbers2 = 'one','two','three'
ERROR: Cannot convert value "one" to type "System.Int32". Input string was not in a correct format."
PS> [string[]] $strings = 'one','two','three'
ArrayList
向数组添加项目是其最大的限制之一,但是我们可以使用其他一些集合来解决这个问题。
当我们需要一个运行速度更快的数组时,ArrayList 通常是我们首先想到的事情之一。它的作用就像一个对象数组,我们需要它的每个地方,但它可以快速处理添加项目。
以下是我们如何创建 ArrayList 并向其中添加项目。
$myarray = [System.Collections.ArrayList]::new()
[void]$myArray.Add('Value')
我们正在调用 .NET 来获取此类型。在本例中,我们使用默认构造函数来创建它。然后我们调用 Add
方法向其中添加一个项目。
我在行开头使用 [void]
的原因是为了抑制返回代码。某些 .NET 调用会执行此操作,并且可能会产生意外的输出。
如果数组中唯一的数据是字符串,那么还可以考虑使用 StringBuilder。它几乎是相同的东西,但有一些仅用于处理字符串的方法。 StringBuilder
专为提高性能而设计。
人们从数组转移到 ArrayList 的情况很常见。但它来自 C# 没有通用支持的时代。已弃用 ArrayList
以支持通用 List[]
通用列表
泛型类型是 C# 中的一种特殊类型,它定义通用类,用户在创建时指定它使用的数据类型。因此,如果您想要一个数字或字符串列表,您可以定义您想要的 int
或 string
类型列表。
以下是创建字符串列表的方法。
$mylist = [System.Collections.Generic.List[string]]::new()
或者一个数字列表。
$mylist = [System.Collections.Generic.List[int]]::new()
我们可以将现有数组转换为这样的列表,而无需先创建对象:
$mylist = [System.Collections.Generic.List[int]]@(1,2,3)
我们可以使用 PowerShell 5 及更高版本中的 using namespace
语句来缩短语法。 using
语句必须是脚本的第一行。通过声明命名空间,PowerShell 允许您在引用数据类型时将其从数据类型中删除。
using namespace System.Collections.Generic
$myList = [List[int]]@(1,2,3)
这使得List
更加有用。
您可以使用类似的 Add
方法。与 ArrayList 不同,Add
方法没有返回值,因此我们不必 void
它。
$myList.Add(10)
我们仍然可以像其他数组一样访问元素。
PS> $myList[-1]
10
List[PSObject]
您可以拥有任何类型的列表,但是当您不知道对象的类型时,可以使用 [List[PSObject]]
来包含它们。
$list = [List[PSObject]]::new()
Remove()
ArrayList
和通用 List[]
都支持从集合中删除项目。
using namespace System.Collections.Generic
$myList = [List[string]]@('Zero','One','Two','Three')
[void]$myList.Remove("Two")
Zero
One
Three
使用值类型时,它会从列表中删除第一个值类型。您可以一遍又一遍地调用它以不断删除该值。如果您有引用类型,则必须提供要删除的对象。
[list[System.Management.Automation.PSDriveInfo]]$drives = Get-PSDrive
$drives.remove($drives[2])
$delete = $drives[2]
$drives.remove($delete)
如果remove方法能够找到并从集合中删除该项目,则它会返回true
。
更多收藏
还有许多其他集合可以使用,但这些是很好的通用数组替代品。如果您有兴趣了解更多这些选项,请查看 Mark Kraus 整理的要点。
其他细微差别
现在我已经介绍了所有主要功能,在总结之前,我还想提一下以下几件事。
预先确定大小的数组
我提到过数组一旦创建就无法更改其大小。我们可以通过使用 new($size)
构造函数调用它来创建一个预定大小的数组。
$data = [Object[]]::new(4)
$data.count
4
数组相乘
一个有趣的小技巧是您可以将数组乘以整数。
PS> $data = @('red','green','blue')
PS> $data * 3
red
green
blue
red
green
blue
red
green
blue
初始化为0
一种常见的情况是您想要创建一个全零的数组。如果您只想使用整数,则强类型整数数组默认为全零。
PS> [int[]]::new(4)
0
0
0
0
我们也可以使用乘法技巧来做到这一点。
PS> $data = @(0) * 4
PS> $data
0
0
0
0
乘法技巧的好处是您可以使用任何值。因此,如果您希望将 255
作为默认值,这将是一个很好的方法。
PS> $data = @(255) * 4
PS> $data
255
255
255
255
嵌套数组
数组内的数组称为嵌套数组。我在 PowerShell 中使用得不多,但在其他语言中使用得较多。当数据适合网格状模式时,请考虑使用数组的数组。
以下是创建二维数组的两种方法。
$data = @(@(1,2,3),@(4,5,6),@(7,8,9))
$data2 = @(
@(1,2,3),
@(4,5,6),
@(7,8,9)
)
在这些例子中逗号非常重要。我之前给出了多行普通数组的示例,其中逗号是可选的。多维数组的情况并非如此。
现在我们有了一个嵌套数组,我们使用索引表示法的方式略有变化。使用上面的 $data
,这就是我们访问值 3 的方式。
PS> $outside = 0
PS> $inside = 2
PS> $data[$outside][$inside]
3
为数组嵌套的每一层添加一组括号。第一组括号用于最外面的数组,然后您可以从那里开始操作。
写输出-NoEnumerate
PowerShell 喜欢解开或枚举数组。这是 PowerShell 使用管道方式的核心方面,但有时您不希望这种情况发生。
我通常通过管道将对象传递给 Get-Member
以了解有关它们的更多信息。当我通过管道将数组传递给它时,它会被解开,并且 Get-Member 看到的是数组的成员,而不是实际的数组。
PS> $data = @('red','green','blue')
PS> $data | Get-Member
TypeName: System.String
...
为了防止数组展开,您可以使用Write-Output -NoEnumerate
。
PS> Write-Output -NoEnumerate $data | Get-Member
TypeName: System.Object[]
...
我有第二种方法,它更像是一种黑客攻击(我试图避免这样的黑客攻击)。您可以在对数组进行管道传输之前在数组前面放置一个逗号。这会将 $data
包装到另一个数组中,它是唯一的元素,因此在展开外部数组后,我们会返回未包装的 $data
。
PS> ,$data | Get-Member
TypeName: System.Object[]
...
返回一个数组
当您从函数输出或返回值时,也会发生这种数组展开。如果将输出分配给变量,您仍然可以获得数组,因此这通常不是问题。
问题是你有一个新数组。如果这是一个问题,您可以使用 Write-Output -NoEnumerate $array
或 return ,$array
来解决它。
还要别的吗?
我知道这需要考虑的内容有很多。我希望您每次阅读本文时都能从中学到一些东西,并且在未来很长一段时间内它都会成为您很好的参考。如果您发现这有帮助,请与您认为可以从中获得价值的其他人分享。
从这里,我建议您查看我写的有关哈希表的类似文章。
猜你还喜欢
- 03-30 [玩转系统] 如何用批处理实现关机,注销,重启和锁定计算机
- 02-14 [系统故障] Win10下报错:该文件没有与之关联的应用来执行该操作
- 01-07 [系统问题] Win10--解决锁屏后会断网的问题
- 01-02 [系统技巧] Windows系统如何关闭防火墙保姆式教程,超详细
- 12-15 [玩转系统] 如何在 Windows 10 和 11 上允许多个 RDP 会话
- 12-15 [玩转系统] 查找 Exchange/Microsoft 365 中不活动(未使用)的通讯组列表
- 12-15 [玩转系统] 如何在 Windows 上安装远程服务器管理工具 (RSAT)
- 12-15 [玩转系统] 如何在 Windows 上重置组策略设置
- 12-15 [玩转系统] 如何获取计算机上的本地管理员列表?
- 12-15 [玩转系统] 在 Visual Studio Code 中连接到 MS SQL Server 数据库
- 12-15 [玩转系统] 如何降级 Windows Server 版本或许可证
- 12-15 [玩转系统] 如何允许非管理员用户在 Windows 中启动/停止服务
取消回复欢迎 你 发表评论:
- 精品推荐!
-
- 最新文章
- 热门文章
- 热评文章
[影视] 黑道中人 Alto Knights(2025)剧情 犯罪 历史 电影
[古装剧] [七侠五义][全75集][WEB-MP4/76G][国语无字][1080P][焦恩俊经典]
[实用软件] 虚拟手机号 电话 验证码 注册
[电视剧] 安眠书店/你 第五季 You Season 5 (2025) 【全10集】
[电视剧] 棋士(2025) 4K 1080P【全22集】悬疑 犯罪 王宝强 陈明昊
[软件合集] 25年6月5日 精选软件22个
[软件合集] 25年6月4日 精选软件36个
[短剧] 2025年06月04日 精选+付费短剧推荐33部
[短剧] 2025年06月03日 精选+付费短剧推荐25部
[软件合集] 25年6月3日 精选软件44个
[剧集] [央视][笑傲江湖][2001][DVD-RMVB][高清][40集全]李亚鹏、许晴、苗乙乙
[电视剧] 欢乐颂.5部全 (2016-2024)
[电视剧] [突围] [45集全] [WEB-MP4/每集1.5GB] [国语/内嵌中文字幕] [4K-2160P] [无水印]
[影视] 【稀有资源】香港老片 艺坛照妖镜之96应召名册 (1996)
[剧集] 神经风云(2023)(完结).4K
[剧集] [BT] [TVB] [黑夜彩虹(2003)] [全21集] [粤语中字] [TV-RMVB]
[实用软件] 虚拟手机号 电话 验证码 注册
[资源] B站充电视频合集,包含多位重量级up主,全是大佬真金白银买来的~【99GB】
[影视] 内地绝版高清录像带 [mpg]
[书籍] 古今奇书禁书三教九流资料大合集 猎奇必备珍藏资源PDF版 1.14G
[电视剧] [突围] [45集全] [WEB-MP4/每集1.5GB] [国语/内嵌中文字幕] [4K-2160P] [无水印]
[剧集] [央视][笑傲江湖][2001][DVD-RMVB][高清][40集全]李亚鹏、许晴、苗乙乙
[电影] 美国队长4 4K原盘REMUX 杜比视界 内封简繁英双语字幕 49G
[电影] 死神来了(1-6)大合集!
[软件合集] 25年05月13日 精选软件16个
[精品软件] 25年05月15日 精选软件18个
[绝版资源] 南与北 第1-2季 合集 North and South (1985) /美国/豆瓣: 8.8[1080P][中文字幕]
[软件] 25年05月14日 精选软件57个
[短剧] 2025年05月14日 精选+付费短剧推荐39部
[短剧] 2025年05月15日 精选+付费短剧推荐36部
- 最新评论
-
- 热门tag