關於陣列
簡短描述
描述陣列,這是設計用來儲存專案集合的資料結構。
完整描述
陣列是設計用來儲存專案集合的資料結構。 專案可以是相同的類型或不同的類型。
從 Windows PowerShell 3.0 開始,零個或一個物件的集合有一些陣列屬性。
建立和初始化陣列
若要建立及初始化陣列,請將多個值指派給變數。 儲存在陣列中的值會以逗號分隔,並使用指派運算子(=)與變數名稱隔開。
例如,若要建立名為 $A 的陣列,其中包含22、5、10、8、12、9和80的七個數值(int)值,請輸入:
$A = 22,5,10,8,12,9,80
您也可以使用範圍運算子(..)來建立和初始化陣列。 例如,若要建立並初始化名為 "$B" 的陣列,其中包含5到8的值,請輸入:
$B = 5..8
因此,$B 包含四個值:5、6、7和8。
當未指定任何資料類型時,PowerShell 會將每個陣列建立為物件陣列(類型: System.object [])。 若要判斷陣列的資料類型,請使用 GetType ()方法。 例如,若要判斷 $a 陣列的資料類型,請輸入:
$a.GetType()
若要建立強型別陣列(也就是只能包含特定類型之值的陣列),請將變數轉換成陣列類型,例如 string []、long [] 或 int32 []。 若要轉換陣列,請在變數名稱前面加上方括弧括住的陣列類型。 例如,若要建立名為的32位整數陣列,$ia 包含四個整數(1500、2230、3350和4000),請輸入:
[int32[]]$ia = 1500,2230,3350,4000
因此,$ia 陣列只能包含整數。
您可以建立在 Microsoft .NET Framework 中轉換成任何支援類型的陣列。 例如,取得處理常式抓取來代表處理常式的物件是由 system.servicemodel 類型所組成。 若要建立處理常式物件的強型別陣列,請輸入下列命令:
[Diagnostics.Process[]]$zz = Get-Process
陣列子運算式運算子
陣列子運算式運算子會建立陣列,即使它包含零個或一個物件。
陣列運算子的語法如下所示:
@( ... )
您可以使用 array 運算子來建立零個或一個物件的陣列。 例如:
PS> $a = @("Hello World")
PS> $a.Count
1
PS> $b = @()
PS> $b.Count
0
當您取得物件時,陣列運算子在腳本中特別有用,但不知道您要取得的物件數目。 例如:
$p = @(Get-Process Notepad)
如需有關陣列子運算式運算子的詳細資訊,請參閱 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
您可以使用索引的範圍運算子來抓取陣列的一部分。 例如,若要取出陣列的第二到第五個元素,您可以輸入:
$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
此外,若要列出多個範圍和個別元素,您可以使用加號運算子。 例如,若要列出從零到二、四到六的專案,以及第八個位置類型的元素:
$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 迴圈來顯示陣列中的元素,直到定義的條件不再成立為止。 例如,若要在 $a
陣列索引小於4時顯示陣列中的元素,請輸入:
$a = 0..9
$i=0
while($i -lt 4) {
$a[$i];
$i++
}
0
1
2
3
陣列的屬性
Count 或 Length 或 LongLength
若要判斷陣列中有多少專案,請使用 Length
屬性或其 Count
別名。 Longlength
如果陣列包含超過2147483647個元素,這會很有用。
$a = 0..9
$a.Count
$a.Length
10
10
排名
傳回陣列中的維度數目。 PowerShell 中的大部分陣列只有一個維度。 即使您認為要建立多維陣列,如下列範例所示:
$a = @(
@(0,1),
@("b", "c"),
@(Get-Process)
)
[int]$r = $a.Rank
"`$a rank: $r"
$a rank: 1
在 PowerShell 中建立真正的多維陣列,需要 .Net Framework的協助。 如下列範例所示:
[int[,]]$rank2 = [int[,]]::new(5,5)
$rank2.rank
2
陣列的方法
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(type convertToType)
ForEach(string propertyName)
ForEach(string propertyName, object[] newValue)
ForEach(string methodName)
ForEach(string methodName, object[] arguments)
ForEach(scriptblock expression, object[] arguments)
ForEach (scriptblock 運算式)
ForEach (scriptblock 運算式,object [] 引數)
注意
語法需要使用腳本區塊。 括弧是選擇性的。
下列範例顯示如何使用 foreach 方法。 在此情況下,目的是要產生陣列中元素的平方值。
請注意,此方法已在 PowerShell v4 中新增,且在此版本底下無法使用。 針對舊版,請使用管線方法來執行 ForEach-Object Cmdlet
$a = @(0 .. 3)
$a.ForEach({ $_ * $_})
0
1
4
9
如同的 -ArgumentList
參數 ForEach-Object
, arguments
參數允許將引數陣列傳遞至已設定接受它們的腳本區塊。
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 (字串方法名稱)
ForEach (string 方法,object [] 引數)
最後, ForEach
方法可以用來對集合中的每個專案執行方法。
("one", "two", "three").ForEach("ToUpper")
ONE
TWO
THREE
如同的 -ArgumentList
參數 ForEach-Object
, arguments
參數允許將引數陣列傳遞至已設定接受它們的腳本區塊。
注意
從 Windows PowerShell 3.0 開始,您也可以使用「純量物件和集合的方法」來取得集合中每個專案的屬性和執行方法,您可以在這裡閱讀更多相關資訊about_methods
Where
允許篩選或選取陣列的元素。 腳本必須評估為下列專案以外的任何專案:零(0)、空字串, $false
或 $null
要顯示在Where
方法有一個定義 Where
。
Where(scriptblock expression[, WhereOperatorSelectionMode mode
[, int numberToReturn]])
Expression
是篩選所需的 scriptblock, mode
選擇性引數允許其他選取功能,而 numberToReturn
選擇性引數允許限制從篩選傳回的專案數。
注意
語法需要使用腳本區塊。 括弧是選擇性的。
下列範例顯示如何從陣列中選取所有奇數。
(0..9).Where{ $_ % 2 }
1
3
5
7
9
可用的選項模式如下。
預設
此 Default
模式會使用 scriptblock 來篩選項目 Expression
。
如果 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
模式會反轉 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
...
取得陣列的成員
若要取得陣列的屬性和方法,例如 Length 屬性和 SetValue 方法,請使用取得成員 Cmdlet 的 InputObject 參數。
當您使用管線將陣列傳送至時 Get-Member
,PowerShell 會一次傳送一個專案,並傳回 Get-Member
陣列中每個專案的類型(忽略重複項)。
當您使用 -InputObject參數時,會傳回 Get-Member
陣列的成員。
例如,下列命令會取得 $a
陣列變數的成員。
Get-Member -InputObject $a
您也可以在輸送至取得成員 Cmdlet 的值之前輸入逗號(,),以取得陣列的成員。 逗號會使陣列成為陣列陣列中的第二個專案。 Windows PowerShell 會一次為一個陣列進行管道傳送,而取得成員則會傳回陣列的成員。 如同接下來的兩個範例。
,$a | Get-Member
,(1,2,3) | Get-Member
運算元組
您可以變更陣列中的元素、將專案新增至陣列,以及將兩個數組的值結合成第三個數組。
若要變更陣列中特定元素的值,請指定陣列名稱稱和您要變更之專案的索引,然後使用指派運算子(=)來指定專案的新值。 例如,若要將陣列(索引位置1)中第二個專案的值變更 $a
為10,請輸入:
$a[1] = 10
您也可以使用陣列的 SetValue 方法來變更值。 下列範例會將陣列的第二個值(索引位置1)變更 $a
為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,但是指派的值 $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