簡短描述
描述陣列,陣列是旨在存儲項集合的數據結構。
完整描述
陣列是一種數據結構,旨在存儲專案集合。 這些項可以是相同類型或不同類型的。
從 Windows PowerShell 3.0 開始,零個或一個物件的集合具有陣列的某些屬性。
創建和初始化陣列
要創建和初始化陣列,請為變數分配多個值。 陣列中存儲的值用逗號分隔,並用賦值運算符 ()= 與變數名稱分隔。
例如,要創建一個名為 $A 的數位,其中包含 22、5、10、8、12、9 和 80 這七個數位 (int) 值,請鍵入:
$A = 22,5,10,8,12,9,80
逗號還可用於初始化單個項數位,方法是將逗號放在單個項之前。
例如,要建立一個包含單個值 7 的單 $B 項陣列,請鍵入:
$B = ,7
您還可以使用範圍運算子 ().. 建立和初始化陣列。
以下示例創建一個包含值 5 到 8 的陣列。
$C = 5..8
因此, $C 包含四個值:5、6、7 和 8。
如果未指定數據類型,PowerShell 會將每個數位創建為物件陣列 (System.Object[])。 要確定陣列的數據類型,請使用 GetType() 方法。 例如,要確定陣列的 $A 資料類型,請鍵入:
$A.GetType()
要創建強類型陣列(即只能包含特定類型值的陣列),請將變數強制轉換為數位類型,例如 string[]、long[] 或 int32[]。 若要強制轉換陣列,請在變數 name 前面加上用方括弧括起來的數位類型。 例如,要創建一個包含四個整數(1500、2230、3350 和 4000)的 $ia 32 位整數數位,請鍵入:
[int32[]]$ia = 1500,2230,3350,4000
因此, $ia 陣列只能包含整數。
可以創建轉換為 .NET 中任何受支援類型的陣列。 例如, Get-Process 檢索以表示進程的物件是 System.Diagnostics.Process 類型。 要建立行程物件的強類型陣列,請輸入以下命令:
[Diagnostics.Process[]]$zz = Get-Process
陣列子表達式運算子
array 子表達式運算符從其中的語句創建一個陣列。 無論 Operator 內部的語句生成什麼,Operator 都會將其放置在陣列中。 即使有零個或一個物件。
陣列運算子的語法如下:
@( ... )
您可以使用 array 運算子建立包含零個或一個物件的陣列。 例如:
$a = @("Hello World")
$a.Count
1
$b = @()
$b.Count
0
陣列運算子在腳本中當你獲取物件時很有用,但不知道你獲取了多少個物件。 例如:
$p = @(Get-Process Notepad)
有關 array 子運算式運算子的更多資訊,請參閱 about_Operators。
訪問和使用陣列元素
讀取陣列
您可以使用數位的變數名稱來參考數位。 要顯示陣列中的所有元素,請鍵入數位名稱。 例如,假設 $a 是一個包含整數 0、1、2 到 9 的陣列;鍵入:
$a
0
1
2
3
4
5
6
7
8
9
您可以使用索引引用陣列中的元素,從位置 0 開始。 將索引弧括在括弧中。 例如,若要顯示 $a 陣列中的第一個專案,請輸入:
$a[0]
0
要顯示陣列中的 $a 第三個元素,請鍵入:
$a[2]
2
您可以使用索引的 range 運算子檢索陣列的一部分。 例如,要檢索陣列的第二個到第五個元素,您可以鍵入:
$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
此外,要列出多個範圍和單個元素,您可以使用 plus 運算符。 例如,要列出元素 0 到 2、4 到 6 以及第 8 個位置的元素類型:
$a = 0..9
$a[+0..2+4..6+8]
0
1
2
4
5
6
8
陣列元素的反覆運算
您還可以使用循環構造(如 ForEach、 For和 While loops)來引用數位中的元素。 例如,要使用 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 循環來顯示陣列中的元素,直到定義的條件不再成立為止。 例如,要在陣列索引小於 4 時顯示陣列中的 $a 元素,請鍵入:
$a = 0..9
$i=0
while($i -lt 4) {
$a[$i]
$i++
}
0
1
2
3
陣列的屬性
Count、Length 或 LongLength
要確定陣列中有多少項,請使用 Length property 或其 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
要訪問多維陣列中的專案,請在一組方括弧 ()[] 中使用逗號 (), 分隔索引。
對多維數位的某些作(如複製和串聯)需要將該陣列展平。 展平將陣列轉換為無約束類型的一維陣列。 產生的陣列會依數據列主要順序接受所有元素。 請考慮下列範例:
$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專案。
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
就像的-ArgumentList參數一樣ForEach-Object,該arguments參數允許將參數數位傳遞給配置為接受參數的腳本塊。
如需 ArgumentList行為的詳細資訊,請參閱 about_Splatting。
ForEach(鍵入 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(字串 propertyName)
ForEach(字串 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(字串 methodName)
ForEach(字串 methodName, object[] 參數)
最後, ForEach 方法可用於對集合中的每個項目執行方法。
("one", "two", "three").ForEach("ToUpper")
ONE
TWO
THREE
就像的參數ForEach-Object一樣-ArgumentList,該Arguments參數允許將值陣列傳遞給配置為接受值的腳本塊。
備註
從 Windows PowerShell 3.0 開始,還可以使用“標量物件和集合的方法”來檢索集合中每個項的屬性和執行方法。 您可以在此處閱讀更多相關信息 about_methods.
哪裡
允許篩選或選擇陣列的元素。 文稿的計算結果必須為以下值:零 (0)、空字串, $false 或者 $null 元素顯示在 Where. 有關布爾值計算的更多資訊,請參閱 about_Booleans。
該方法 Where 有一個定義。
Where(scriptblock expression[, WhereOperatorSelectionMode mode
[, int numberToReturn]])
備註
該語法需要使用腳本塊。 如果 scriptblock 是唯一的參數,則括弧是可選的。 此外,方法與左括弧或大括弧之間不得有空格。
Expression篩選所需的is腳本塊,modeoptional 參數允許其他選擇功能,optional numberToReturn 參數允許限制從篩選器返回的項目數。
可接受的值 mode 為:
- 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 篩選專案。
如果提供 a 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 返回 BEFORE the first pass 的專案。
SkipUntil返回第一次傳遞之後的所有專案,包括第一個傳遞的專案。
Split
該 Split 模式將集合項拆分或分組為兩個單獨的集合。 傳遞 scriptblock 表達式的函數和不傳遞 scriptblock 表達式的函數。
如果指定了
其餘物件(甚至是那些 PASS 運算式 filter 的物件)將在第二個集合中返回。
$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
...
備註
both foreach 和 where methods 都是內部成員。 有關內部成員的更多資訊,請參閱 about_Instrinsic_Members
獲取陣列的成員
若要獲取數位的屬性和方法(如Length屬性和 SetValue 方法),請使用 cmdlet 的 Get-MemberInputObject 參數。
當您通過管道將陣列傳遞給 Get-Member時,PowerShell 一次發送一個項,並 Get-Member 返回數位中每個項的類型(忽略重複項)。
使用 InputObject 參數時, Get-Member 返回數位的成員。
例如,以下命令獲取array變數的成員 $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 實際上會使用原始數位的值和添加的值創建一個新陣列。 如果作重複多次或數位大小太大,這可能會導致性能問題。
從陣列中刪除元素並不容易,但您可以創建一個僅包含現有數位的選定元素的新陣列。 例如,要建立 $t 包含數位中 $a 除索引位置 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,但分配值 NAME $null 會更快,尤其是對於大型陣列。
零個或1個陣列
從 Windows PowerShell 3.0 開始,零個或一個物件的集合具有 Count and Length 屬性。 此外,還可以索引到一個對象的陣列中。 此功能可説明您避免在需要集合的命令獲得少於兩個項時發生腳本錯誤。
以下示例演示了此功能。
零物件
$a = $null
$a.Count
$a.Length
0
0
一個物件
$a = 4
$a.Count
$a.Length
$a[0]
$a[-1]
1
1
4
4
System.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 對象在通過管道傳遞時或由支援物件陣列的參數視為單個物件。
有關詳細資訊,請參閱 System.Tuple.
成員訪問枚舉
從 PowerShell 3.0 開始,當您使用 member-access 運算符訪問清單集合上不存在的成員時,PowerShell 會自動枚舉集合中的項,並嘗試訪問每個項上的指定成員。 如需詳細資訊,請參閱 about_Member-Access_Enumeration。
範例
以下範例建立兩個新檔,並將生成的物件儲存在array變數 $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.
要設置值,您必須使用 method.
$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 物件的隱藏成員。 下面的示例演示如何查找具有 hiddenset 方法的成員。
$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;}
謹慎
由於該方法是針對集合中的每個項執行的,因此在使用成員枚舉調用方法時應小心。