關於陣列

簡短描述

描述陣列,這是設計用來儲存專案集合的資料結構。

完整描述

陣列是設計來儲存專案集合的資料結構。 專案可以是相同類型或不同的類型。

從 Windows PowerShell 3.0 開始,零或一個物件的集合具有陣列的某些屬性。

建立和初始化陣列

若要建立和初始化陣列,請將多個值指派給變數。 儲存在陣列中的值會以逗號分隔,並以指派運算子分隔變數名稱, (=) 。

例如,若要建立名為 $A 的陣列,其中包含 22、5、10、8、12、9 和 80 的七個數值 (int) 值,請輸入:

$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 資料類型,請輸入:

$A.GetType()

若要建立強型別陣列,也就是只能包含特定型別值的陣列,請將變數轉換成陣列類型,例如string[]long[]int32[]。 若要轉換陣列,請在變數名稱前面加上括弧括住的陣列類型。 例如,若要建立名為 的 32 位整數陣列,其中包含 $ia 四個整數, (1500、2230、3350 和 4000) ,請輸入:

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

因此, $ia 陣列只能包含整數。

您可以在 Microsoft .NET Framework中建立轉換成任何支援的型別的陣列。 例如,擷取來表示進程的物件 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、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 迴圈來顯示陣列中的元素,直到定義的條件不再成立為止。 例如,若要在陣列索引小於 4 時顯示陣列中的 $a 專案,請輸入:

$a = 0..9
$i=0
while($i -lt 4) {
  $a[$i];
  $i++
}
0
1
2
3

陣列的屬性

Count 或 Length 或 LongLength

若要判斷陣列中的專案數目,請使用 Length 屬性或其 Count 別名。 Longlength 如果陣列包含超過 2,147,483,647 個元素,則很有用。

$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

下列範例示範如何使用 .Net Framework 建立真正的多維度陣列。

[int[,]]$rank2 = [int[,]]::new(5,5)
$rank2.rank
2

陣列的方法

清除

將所有專案值設定為數組專案類型的 預設值 。 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[] arguments)

最後, ForEach 方法可以用來在集合中的每個專案上執行方法。

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

就像 的 -ArgumentListForEach-Object 參數一 arguments 樣,參數允許將引數陣列傳遞至設定為接受它們的腳本區塊。

注意

從 Windows PowerShell 3.0 開始,擷取屬性並執行集合中每個專案的方法也可以使用「純量物件和集合的方法」來完成。您可以在這裡閱讀about_methods。

Where

允許篩選或選取陣列的專案。 腳本必須評估為以外的任何專案:零 (0) 、空字串, $false$null 專案在 之後顯示 Where

方法有一個定義 Where

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

注意

語法需要使用腳本區塊。 如果 scriptblock 是唯一的參數,則括弧是選擇性的。 此外,方法與左括弧或大括弧之間不得有空格。

Expression是篩選所需的 scriptblock、 mode 選擇性引數允許其他選取功能,而 numberToReturn 選擇性引數允許限制從篩選傳回的專案數。

可接受的值為 mode

  • 預設 (0) - 傳回所有專案
  • 第一個 (1) - 傳回第一個專案
  • 上次 (2) - 傳回最後一個專案
  • SkipUntil (3) - 在條件為 true 之前略過專案,傳回剩餘的專案
  • 直到 (4) - 傳回所有專案,直到條件為 true 為止
  • 分割 (5) - 傳回兩個元素的陣列
    • 第一個專案包含相符的專案
    • 第二個專案包含其餘專案

下列範例示範如何從陣列中選取所有奇數。

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

此範例示範如何選取不是空的字串。

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

預設

模式會 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 會反轉 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會傳回第一次通過之前的專案。

SkipUntil會傳回第一次通過之後的所有專案,包括第一個傳遞專案。

分割

模式會將 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
...

取得陣列的成員

若要取得陣列的屬性和方法,例如 Length 屬性和SetValue方法,請使用 Cmdlet 的 Get-MemberInputObject參數。

當您使用管線將陣列傳送至 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 屬性。 此外,您可以將索引編制成一個物件的陣列。 這項功能可協助您避免在預期集合的命令取得少於兩個專案時發生的腳本錯誤。

下列範例示範這項功能。

零物件

$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

另請參閱