您想要知道陣列的一切

數位是大部分程式設計語言的基本語言功能。 它們是難以避免的值或物件的集合。 讓我們仔細看看陣列及其提供的所有專案。

注意

本文的原始版本出現在@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] 提供您與陣列中第一個和最後一個專案的值相同 $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 陣列的索引

如果您的變數是 $null ,而且您嘗試像數位一樣編製索引,就會收到 System.Management.Automation.RuntimeException 訊息的例外狀況 Cannot index into a null array

PS> $empty = $null
PS> $empty[0]
Error: Cannot index into a null array.

因此,請先確定您的陣列不是 $null 在您嘗試存取這些陣列內的元素之前。

計數

陣列和其他集合具有 count 屬性,告訴您陣列中的項目數目。

PS> $data.count
4

PowerShell 3.0 已將 count 屬性新增至大多數物件。 您可以有單一物件,而且它應該會提供計數 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

李戴利還向我指出,我們可以用來 $data.GetUpperBound(0) 取得最大索引編號。

PS> $data.GetUpperBound(0)
3
PS> $data[ $data.GetUpperBound(0) ]
Three

第二個最常見的方式是反覆運算清單,而不是在正確的時間停止。 當我們談論使用 for 迴圈時,我會重新審視這個。

更新專案

我們可以使用相同的索引來更新陣列中的現有專案。 這可讓我們直接存取以更新個別專案。

$data[2] = 'dos'
$data[3] = 'tres'

如果我們嘗試更新超過最後一個專案的專案,則會收到 Index was outside the bounds 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 ( <variable> in <collection> )

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]
}

我們做的第一件事是將 初始化 $index0。 然後,我們會新增必須小於 $data.count的條件$index。 最後,我們指定每次循環時,都必須將索引增加為 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 語句執行許多酷的事情。 我有另一篇文章專門說明這一點。

更新值

當您的陣列是字串或整數的集合時,有時候您可能會想要在迴圈查看這些值時更新陣列中的值。 上述大部分的循環都會使用迴圈中的變數來保存值的複本。 如果您更新該變數,則陣列中的原始值不會更新。

該語句的例外狀況是 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 篩選

這是傳入的位置 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 運算符,並經常使用它。 它會聯結陣列中的所有專案,以及您指定的字元或字串。

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.

-join $array

這是李戴利向我指出的一個聰明的技巧。 如果您想要加入不含分隔符的所有專案,而不是這麼做:

PS> $data = @(1,2,3,4)
PS> $data -join $null
1234

您可以使用 -join 陣列做為不含前置詞的參數。 看看這個範例,看看我在談論。

PS> $data = @(1,2,3,4)
PS> -join $data
1234

-replace 和 -split

其他運算元,例如 -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 可讓您檢查值的陣列,以查看其是否包含指定的值。

PS> $data = @('red','green','blue')
PS> $data -contains 'green'
True

-in

當您有想要驗證的單一值符合數個值之一時,您可以使用 -in 運算符。 值會位於左邊,而運算子右邊的陣列則為 。

PS> $data = @('red','green','blue')
PS> 'green' -in $data
True

如果清單很大,這可能會變得很昂貴。 如果我檢查多個值,我通常會使用 regex 模式。

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 會嘗試比對集合中的每個專案。

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 一篇文章中的 變數稱為 使用 regex 的很多方式。

$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"
}

All -eq

我最近看到有人詢問 如何確認陣列中的每個值都符合指定的值。 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

Plus 等於 +=

我們可以就地建立新的陣列,並將專案新增至它,如下所示:

$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# 中的特殊類型,定義一般化類別,而使用者指定建立時所使用的數據類型。 因此,如果您想要數位或字串清單,您可以定義您想要清單 intstring 類型。

以下是建立字串清單的方式。

$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)

如果移除方法能夠從集合中尋找並移除專案,則會傳回 true

更多集合

有許多其他集合可以使用,但這些集合是很好的泛型數位取代專案。 如果您有興趣深入瞭解這些選項,請看看馬克·克勞斯放在一起的這個 Gist

其他細微差別

既然我已經涵蓋了所有主要功能,以下是我總結之前想要提及的一些事項。

預先大小的陣列

我提到,一旦建立陣列,就無法變更陣列的大小。 我們可以使用建構函式呼叫它 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

為每個數位巢狀層級新增一組括弧。 第一組括弧適用於最外層數位,然後從該處開始工作。

Write-Output -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[]
...

傳回陣列

當您從函式輸出或傳回值時,也會發生陣列解除包裝的情況。 如果您將輸出指派給變數,因此這不是常見的問題,您仍然可以取得陣列。

catch 是您有新的陣列。 如果這是問題,您可以使用 Write-Output -NoEnumerate $arrayreturn ,$array 來解決此問題。

別的東西?

我知道這一切都是很多要接受的。 我希望你每次閱讀這篇文章時都會從這篇文章中學到一些東西,而且它被證明是一個很好的參考,給你很長一段時間。 如果您發現這很有説明,請與您認為可能會從中得到價值的其他人員分享。

從這裡,我建議您查看我撰寫的類似文章哈希