about_Arrays
簡短描述
描述陣列,這是設計來儲存專案集合的數據結構。
完整描述
數位是設計來儲存專案集合的數據結構。 專案可以是相同類型或不同的類型。
從 Windows PowerShell 3.0 開始,零或一個 物件的集合具有陣列的某些屬性。
建立和初始化陣列
若要建立和初始化陣列,請將多個值指派給變數。 儲存在陣列中的值會以逗號分隔,並以指派運算符分隔變數名稱 (=
) 。
例如,若要建立名為 $A
的陣列,其中包含7個數值 (整數) 值為22、5、10、8、12、9和80,請輸入:
$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
此外,若要列出多個範圍和個別元素,您可以使用 plus 運算符。 例如,若要列出零到二的專案、四到六,以及第八個位置類型的元素:
$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
循環來顯示陣列中的元素,直到定義的條件不再成立為止。 例如,若要在陣列索引小於 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
若要存取多維度陣列中的專案,請使用逗號分隔索引 (,
) 單一方括弧 []
() 。
多維度陣列上的某些作業,例如復寫和串連,需要扁平化該陣列。 壓平合併會將數位轉換成非限制類型的1D陣列。 產生的陣列會採用數據列主要順序的所有元素。 請思考一下下列範例:
$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
是一個 1 維陣列,其中包含來自 $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
就像的 ForEach-Object
ArgumentList 參數一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 (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[] 自變數)
Lastly, 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
是篩選所需的 scriptblock、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
注意
和 SkipUntil
都會Until
在 NOT 測試一批項目的情況下運作。
Until
會傳回第一個PASS之前的專案。 SkipUntil
會傳回第一次通過之後的所有專案,包括第一個傳遞的專案。
Split
模式會將 Split
集合專案分割成兩個不同的集合。 傳遞 scriptblock 表達式的運算式,以及未傳遞的表達式。
如果指定了 numberToReturn
,則第一個集合會包含 傳遞 的專案,而不是超過指定的值。
其餘物件,即使是 PASS 運算式篩選條件的物件,也會在第二個集合中傳回。
$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
...
注意
和 Where()
方法都是ForEach()
內部成員。 如需內部成員的詳細資訊,請參閱 about_Instrinsic_Members。
取得陣列的成員
若要取得數位的屬性和方法,例如 Length 屬性和 SetValue 方法,請使用 Cmdlet 的 Get-Member
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 方法來變更值。 下列範例會將陣列的第二個值 (索引位置 1) $a
變更為 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 屬性。 此外,您可以將索引編製成一個對象的陣列。 這項功能可協助您避免在預期集合的命令取得少於兩個專案時發生的腳本錯誤。
下列範例顯示不包含任何 物件的變數具有 Count 和 Length 0。
PS> $a = $null
PS> $a.Count
0
PS> $a.Length
0
下列範例顯示包含一個 物件的變數具有 Count 和 Length 1。 您也可以使用數位索引來存取物件的值。
PS> $a = 4
PS> $a.Count
1
PS> $a.Length
1
PS> $a[0]
4
PS> $a[-1]
4
當您執行可傳回集合或單一物件的命令時,您可以使用數位件索引來存取物件的值,而不需要測試 Count 或 Length 屬性。 不過,如果結果為單一物件 (單一物件) ,且該物件具有 Count 或 Length 屬性,則這些屬性的值屬於單一物件,且不代表集合中的項目數。
在下列範例中,命令會傳回單一字串物件。 Length這個字串的 是 4
。
PS> $result = 'one','two','three','four' | Where-Object {$_ -like 'f*'}
PS> $result.GetType().FullName
System.String
PS> $result
four
PS> $result.Count
1
PS❯ $result.Length
4
如果您想要 $result
是字串陣列,您必須將變數宣告為陣列。
在此範例中, $result
是字串數位。 陣列 Count 的 和 Length 為 1
,而 Length 第一個專案的 是 4
。
PS> [string[]]$result = 'one','two','three','four' |
Where-Object {$_ -like 'f*'}
PS> $result.GetType().FullName
System.String[]
PS> $result
four
PS> $result.Count
1
PS> $result.Length
1
PS> $result[0].Length
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 物件會被視為單一物件。
如需詳細資訊,請參閱 System.Tuple。
為實作的 .NET 型別編製索引 IDictionary<TKey, TValue>
PowerShell 不會針對實作泛型 IDictionary<TKey, TValue>
介面的類型呼叫類型真正的索引器。 相反地,當指定金鑰時,PowerShell 會使用 TryGetValue()
測試密鑰是否存在,這會在索引鍵不存在時傳回 $null
。
相較之下,如果您使用呼叫類型的 true 索引器 Item(<key>)
,方法會在索引鍵不存在時擲回例外狀況。
下列範例會說明其間的差異。
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 成員,所以會針對數位中的每個項目傳回 WriteTime 的值Last。
$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;}
警告
由於方法會針對集合中的每個項目執行,因此在使用成員列舉呼叫方法時,應該小心。