Semua yang ingin Anda ketahui tentang array

Array adalah fitur bahasa dasar dari sebagian besar bahasa pemrograman. Ini adalah kumpulan nilai atau objek yang sulit dihindari. Mari kita lihat lebih dekat array dan semua yang mereka tawarkan.

Catatan

Versi asli artikel ini muncul di blog yang ditulis oleh @KevinMarquette. Tim PowerShell berterima kasih kepada Kevin karena telah membagikan konten ini kepada kami. Silakan lihat blognya di PowerShellExplained.com.

Apa itu array?

Saya akan mulai dengan deskripsi teknis dasar tentang array apa dan bagaimana mereka digunakan oleh sebagian besar bahasa pemrograman sebelum saya beralih ke cara lain PowerShell memanfaatkannya.

Array adalah struktur data yang berfungsi sebagai kumpulan beberapa item. Anda dapat melakukan iterasi melalui array atau mengakses item individual menggunakan indeks. Array dibuat sebagai potongan memori berurutan di mana setiap nilai disimpan tepat di samping yang lain.

Akan kusentuh masing-masing detailnya saat kita pergi.

Penggunaan dasar

Karena array adalah fitur dasar PowerShell, ada sintaks sederhana untuk bekerja dengannya di PowerShell.

Membuat array

Array kosong dapat dibuat dengan menggunakan @()

PS> $data = @()
PS> $data.count
0

Kita dapat membuat array dan menambahkannya dengan nilai hanya dengan menempatkannya di @() tanda kurung.

PS> $data = @('Zero','One','Two','Three')
PS> $data.count
4

PS> $data
Zero
One
Two
Three

Array ini memiliki 4 item. Ketika kita memanggil $data variabel, kita melihat daftar item kita. Jika itu adalah array string, maka kita mendapatkan satu baris per string.

Kita dapat mendeklarasikan array pada beberapa baris. Koma bersifat opsional dalam hal ini dan umumnya ditinggalkan.

$data = @(
    'Zero'
    'One'
    'Two'
    'Three'
)

Saya lebih suka mendeklarasikan array saya pada beberapa baris seperti itu. Tidak hanya menjadi lebih mudah untuk dibaca ketika Anda memiliki beberapa item, itu juga membuatnya lebih mudah untuk dibandingkan dengan versi sebelumnya saat menggunakan kontrol sumber.

Sintaksis lainnya

Biasanya dipahami bahwa @() adalah sintaks untuk membuat array, tetapi daftar yang dipisahkan koma berfungsi sebagian besar waktu.

$data = 'Zero','One','Two','Three'

Write-Output untuk membuat array

Salah satu trik kecil keren yang layak disebutkan adalah Anda dapat menggunakan Write-Output untuk membuat string dengan cepat di konsol.

$data = Write-Output Zero One Two Three

Ini berguna karena Anda tidak perlu menempatkan tanda kutip di sekitar string saat parameter menerima string. Saya tidak akan pernah melakukan ini dalam naskah tetapi itu permainan yang adil di konsol.

Mengakses item

Sekarang setelah Anda memiliki array dengan item di dalamnya, Anda mungkin ingin mengakses dan memperbarui item tersebut.

Offset

Untuk mengakses item individual, kami menggunakan tanda kurung siku [] dengan nilai offset mulai dari 0. Ini adalah cara kita mendapatkan item pertama dalam array kita:

PS> $data = 'Zero','One','Two','Three'
PS> $data[0]
Zero

Alasan mengapa kita menggunakan nol di sini adalah karena item pertama berada di awal daftar sehingga kita menggunakan offset 0 item untuk mendapatkannya. Untuk sampai ke item kedua, kita perlu menggunakan offset 1 untuk melewati item pertama.

PS> $data[1]
One

Ini berarti bahwa item terakhir berada di offset 3.

PS> $data[3]
Three

Indeks

Sekarang Anda dapat melihat mengapa saya memilih nilai yang saya lakukan untuk contoh ini. Saya memperkenalkan ini sebagai offset karena itulah sebenarnya, tetapi offset ini lebih umum disebut sebagai indeks. Indeks yang dimulai pada 0. Untuk sisa artikel ini, saya akan menyebut offset indeks.

Trik indeks khusus

Dalam sebagian besar bahasa, Anda hanya dapat menentukan satu angka sebagai indeks dan Anda mendapatkan satu item kembali. PowerShell jauh lebih fleksibel. Anda dapat menggunakan beberapa indeks sekaligus. Dengan menyediakan daftar indeks, kita dapat memilih beberapa item.

PS> $data[0,2,3]
Zero
Two
Three

Item dikembalikan berdasarkan urutan indeks yang disediakan. Jika Anda menduplikasi indeks, Anda mendapatkan item tersebut dua kali.

PS> $data[3,0,3]
Three
Zero
Three

Kita dapat menentukan urutan angka dengan operator bawaan .. .

PS> $data[1..3]
One
Two
Three

Ini juga berfungsi secara terbalik.

PS> $data[3..1]
Three
Two
One

Anda dapat menggunakan nilai indeks negatif untuk mengimbangi dari akhir. Jadi, jika Anda memerlukan item terakhir dalam daftar, Anda dapat menggunakan -1.

PS> $data[-1]
Three

Satu kata hati-hati di sini dengan .. operator. Urutan 0..-1 dan -1..0 evaluasi ke nilai 0,-1 dan -1,0. Sangat mudah untuk melihat $data[0..-1] dan berpikir itu akan menghitung semua item jika Anda lupa detail ini. $data[0..-1] memberi Anda nilai yang sama seperti $data[0,-1] dengan memberi Anda item pertama dan terakhir dalam array (dan tidak ada nilai lainnya). Berikut adalah contoh yang lebih besar:

PS> $a = 1,2,3,4,5,6,7,8
PS> $a[2..-1]
3
2
1
8

Ini sama dengan:

PS> $a[2,1,0,-1]
3
2
1
8

Di luar batas

Dalam sebagian besar bahasa, jika Anda mencoba mengakses indeks item yang melewati akhir array, Anda akan mendapatkan beberapa jenis kesalahan atau pengecualian. PowerShell secara diam-diam tidak mengembalikan apa pun.

PS> $null -eq $data[9000]
True

Tidak dapat mengindeks ke dalam array null

Jika variabel Anda adalah $null dan Anda mencoba mengindeksnya seperti array, Anda mendapatkan System.Management.Automation.RuntimeException pengecualian dengan pesan Cannot index into a null array.

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

Jadi pastikan array Anda tidak $null sebelum Anda mencoba mengakses elemen di dalamnya.

Jumlah

Array dan koleksi lainnya memiliki properti hitungan yang memberi tahu Anda berapa banyak item dalam array.

PS> $data.count
4

PowerShell 3.0 menambahkan properti hitungan ke sebagian besar objek. Anda dapat memiliki satu objek dan itu harus memberi Anda hitungan 1.

PS> $date = Get-Date
PS> $date.count
1

Bahkan $null memiliki properti hitungan kecuali mengembalikan 0.

PS> $null.count
0

Ada beberapa perangkap di sini yang akan saya kunjungi kembali ketika saya membahas memeriksa atau mengosongkan $null array nanti di artikel ini.

Kesalahan off-by-one

Kesalahan pemrograman umum dibuat karena array dimulai pada indeks 0. Kesalahan off-by-one dapat diperkenalkan dengan dua cara.

Yang pertama adalah dengan berpikir mental Anda menginginkan item kedua dan menggunakan indeks 2 dan benar-benar mendapatkan item ketiga. Atau dengan berpikir bahwa Anda memiliki empat item dan Anda menginginkan item terakhir, jadi Anda menggunakan hitungan untuk mengakses item terakhir.

$data[ $data.count ]

PowerShell sangat senang membiarkan Anda melakukan itu dan memberi Anda item apa yang ada di indeks 4: $null. Anda harus menggunakan $data.count - 1 atau -1 yang kita pelajari di atas.

PS> $data[ $data.count - 1 ]
Three

Di sinilah Anda dapat menggunakan -1 indeks untuk mendapatkan elemen terakhir.

PS> $data[ -1 ]
Three

Lee Dailey juga menunjukkan kepada saya bahwa kita dapat menggunakan $data.GetUpperBound(0) untuk mendapatkan nomor indeks maksimum.

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

Cara kedua yang paling umum adalah ketika melakukan iterasi daftar dan tidak berhenti pada waktu yang tepat. Aku akan melihat kembali ini ketika kita berbicara tentang menggunakan perulangan for .

Memperbarui item

Kita dapat menggunakan indeks yang sama untuk memperbarui item yang ada dalam array. Ini memberi kami akses langsung untuk memperbarui item individual.

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

Jika kita mencoba memperbarui item yang melewati elemen terakhir, maka kita mendapatkan kesalahan 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

Saya akan mengunjungi kembali ini nanti ketika saya berbicara tentang cara membuat array lebih besar.

Iterasi

Pada titik tertentu, Anda mungkin perlu berjalan atau melakukan iterasi seluruh daftar dan melakukan beberapa tindakan untuk setiap item dalam array.

Alur

Array dan alur PowerShell dimaksudkan untuk satu sama lain. Ini adalah salah satu cara paling sederhana untuk memproses nilai-nilai tersebut. Saat Anda meneruskan array ke alur, setiap item di dalam array diproses satu per satu.

PS> $data = 'Zero','One','Two','Three'
PS> $data | ForEach-Object {"Item: [$PSItem]"}
Item: [Zero]
Item: [One]
Item: [Two]
Item: [Three]

Jika Anda belum melihat $PSItem sebelumnya, ketahuilah bahwa itu adalah hal yang sama dengan $_. Anda dapat menggunakan salah satu karena keduanya mewakili objek saat ini dalam alur.

Perulangan ForEach

Perulangan ForEach bekerja dengan baik dengan koleksi. Menggunakan sintaks: foreach ( <variable> in <collection> )

foreach ( $node in $data )
{
    "Item: [$node]"
}

Metode ForEach

Saya cenderung melupakan yang satu ini tetapi bekerja dengan baik untuk operasi sederhana. PowerShell memungkinkan Anda memanggil .ForEach() koleksi.

PS> $data.foreach({"Item [$PSItem]"})
Item [Zero]
Item [One]
Item [Two]
Item [Three]

.foreach() mengambil parameter yang merupakan blok skrip. Anda dapat menghilangkan tanda kurung dan hanya menyediakan blok skrip.

$data.foreach{"Item [$PSItem]"}

Ini adalah sintaks yang kurang diketahui tetapi berfungsi sama. Metode ini foreach ditambahkan di PowerShell 4.0.

Untuk perulangan

Perulangan for banyak digunakan dalam sebagian besar bahasa lain tetapi Anda tidak melihatnya banyak di PowerShell. Ketika Anda melihatnya, sering kali dalam konteks berjalan array.

for ( $index = 0; $index -lt $data.count; $index++)
{
    "Item: [{0}]" -f $data[$index]
}

Hal pertama yang kita lakukan adalah menginisialisasi $index ke 0. Kemudian kita menambahkan kondisi yang $index harus kurang dari $data.count. Akhirnya, kami menentukan bahwa setiap kali kami mengulang bahwa saya harus meningkatkan indeks dengan 1. Dalam hal $index++ ini singkatan dari $index = $index + 1. Operator format (-f) digunakan untuk menyisipkan nilai $data[$index] dalam string output.

Setiap kali Anda menggunakan perulangan for , beri perhatian khusus pada kondisi tersebut. Aku digunakan $index -lt $data.count di sini. Sangat mudah untuk mendapatkan kondisi yang sedikit salah untuk mendapatkan kesalahan off-by-one dalam logika Anda. Menggunakan $index -le $data.count atau $index -lt ($data.count - 1) pernah begitu sedikit salah. Itu akan menyebabkan hasil Anda memproses terlalu banyak atau terlalu sedikit item. Ini adalah kesalahan klasik off-by-one.

Perulangan sakelar

Ini adalah salah satu yang mudah diabaikan. Jika Anda memberikan array ke pernyataan pengalih, array akan memeriksa setiap item dalam array.

$data = 'Zero','One','Two','Three'
switch( $data )
{
    'One'
    {
        'Tock'
    }
    'Three'
    {
        'Tock'
    }
    Default
    {
        'Tick'
    }
}
Tick
Tock
Tick
Tock

Ada banyak hal keren yang dapat kita lakukan dengan pernyataan switch. Saya memiliki artikel lain yang didedikasikan untuk ini.

Memperbarui nilai

Saat array Anda adalah kumpulan string atau bilangan bulat (jenis nilai), terkadang Anda mungkin ingin memperbarui nilai dalam array saat Anda mengulanginya. Sebagian besar perulangan di atas menggunakan variabel dalam perulangan yang menyimpan salinan nilai. Jika Anda memperbarui variabel tersebut, nilai asli dalam array tidak diperbarui.

Pengecualian untuk pernyataan itu adalah perulangan for . Jika Anda ingin menjalankan array dan memperbarui nilai di dalamnya, maka perulangan for adalah apa yang Anda cari.

for ( $index = 0; $index -lt $data.count; $index++ )
{
    $data[$index] = "Item: [{0}]" -f $data[$index]
}

Contoh ini mengambil nilai menurut indeks, membuat beberapa perubahan, lalu menggunakan indeks yang sama untuk menetapkannya kembali.

Array Objek

Sejauh ini, satu-satunya hal yang telah kami tempatkan dalam array adalah jenis nilai, tetapi array juga dapat berisi objek.

$data = @(
    [pscustomobject]@{FirstName='Kevin';LastName='Marquette'}
    [pscustomobject]@{FirstName='John'; LastName='Doe'}
)

Banyak cmdlet mengembalikan koleksi objek sebagai array saat Anda menetapkannya ke variabel.

$processList = Get-Process

Semua fitur dasar yang sudah kita bicarakan masih berlaku untuk array objek dengan beberapa detail yang layak untuk diuraikan.

Mengakses properti

Kita dapat menggunakan indeks untuk mengakses item individual dalam koleksi sama seperti dengan jenis nilai.

PS> $data[0]

FirstName LastName
-----     ----
Kevin     Marquette

Kita dapat mengakses dan memperbarui properti secara langsung.

PS> $data[0].FirstName

Kevin

PS> $data[0].FirstName = 'Jay'
PS> $data[0]

FirstName LastName
-----     ----
Jay       Marquette

Properti array

Biasanya Anda harus menghitung seluruh daftar seperti ini untuk mengakses semua properti:

PS> $data | ForEach-Object {$_.LastName}

Marquette
Doe

Atau dengan menggunakan Select-Object -ExpandProperty cmdlet .

PS> $data | Select-Object -ExpandProperty LastName

Marquette
Doe

Tetapi PowerShell menawarkan kami kemampuan untuk meminta LastName secara langsung. PowerShell menghitung semuanya untuk kita dan mengembalikan daftar yang bersih.

PS> $data.LastName

Marquette
Doe

Enumerasi masih terjadi tetapi kita tidak melihat kompleksitas di baliknya.

pemfilteran Where-Object

Di sinilah Where-Object kita dapat memfilter dan memilih apa yang kita inginkan dari array berdasarkan properti objek.

PS> $data | Where-Object {$_.FirstName -eq 'Kevin'}

FirstName LastName
-----     ----
Kevin     Marquette

Kita dapat menulis kueri yang sama untuk mendapatkan yang FirstName kita cari.

$data | Where FirstName -eq Kevin

Where()

Array memiliki Where() metode yang memungkinkan Anda menentukan scriptblock untuk filter.

$data.Where({$_.FirstName -eq 'Kevin'})

Fitur ini ditambahkan di PowerShell 4.0.

Memperbarui objek dalam perulangan

Dengan jenis nilai, satu-satunya cara untuk memperbarui array adalah dengan menggunakan untuk perulangan karena kita perlu mengetahui indeks untuk mengganti nilai. Kami memiliki lebih banyak opsi dengan objek karena merupakan jenis referensi. Berikut adalah contoh singkatnya:

foreach($person in $data)
{
    $person.FirstName = 'Kevin'
}

Perulangan ini berjalan setiap objek dalam $data array. Karena objek adalah jenis referensi, variabel mereferensikan $person objek yang sama persis yang ada dalam array. Jadi pembaruan untuk propertinya memperbarui yang asli.

Anda masih tidak dapat mengganti seluruh objek dengan cara ini. Jika Anda mencoba menetapkan objek baru ke $person variabel , Anda memperbarui referensi variabel ke sesuatu yang lain yang tidak lagi menunjuk ke objek asli dalam array. Ini tidak berfungsi seperti yang Anda harapkan:

foreach($person in $data)
{
    $person = [pscustomobject]@{
        FirstName='Kevin'
        LastName='Marquette'
    }
}

Operator

Operator di PowerShell juga bekerja pada array. Beberapa dari mereka bekerja sedikit berbeda.

-join

Operator -join adalah yang paling jelas jadi mari kita lihat terlebih dahulu. Saya suka -join operator dan sering menggunakannya. Ini menggabungkan semua elemen dalam array dengan karakter atau string yang Anda tentukan.

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

Salah satu fitur yang saya sukai tentang -join operator adalah ia menangani item tunggal.

PS> 1 -join '-'
1

Saya menggunakan ini di dalam pengelogan dan pesan verbose.

PS> $data = @(1,2,3,4)
PS> "Data is $($data -join ',')."
Data is 1,2,3,4.

-join $array

Berikut adalah trik pintar yang Ditujukan Lee Dailey padaku. Jika Anda ingin bergabung dengan semuanya tanpa pemisah, alih-alih melakukan ini:

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

Anda dapat menggunakan -join dengan array sebagai parameter tanpa awalan. Lihat contoh ini untuk melihat bahwa saya sedang berbicara tentang.

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

-replace dan -split

Operator lain menyukai -replace dan -split mengeksekusi pada setiap item dalam array. Saya tidak bisa mengatakan bahwa saya pernah menggunakannya dengan cara ini tetapi inilah contohnya.

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

Operator -contains memungkinkan Anda memeriksa array nilai untuk melihat apakah berisi nilai yang ditentukan.

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

-in

Ketika Anda memiliki satu nilai yang ingin Anda verifikasi cocok dengan salah satu dari beberapa nilai, Anda dapat menggunakan -in operator . Nilainya akan berada di sebelah kiri dan array di sisi kanan operator.

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

Ini bisa mahal jika daftarnya besar. Saya sering menggunakan pola regex jika saya memeriksa lebih dari beberapa nilai.

PS> $data = @('red','green','blue')
PS> $pattern = "^({0})$" -f ($data -join '|')
PS> $pattern
^(red|green|blue)$

PS> 'green' -match $pattern
True

-eq dan -ne

Kesetaraan dan array bisa menjadi rumit. Saat array berada di sisi kiri, setiap item akan dibandingkan. Alih-alih mengembalikan True, ini mengembalikan objek yang cocok.

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

Saat Anda menggunakan -ne operator , kami mendapatkan semua nilai yang tidak sama dengan nilai kami.

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

Saat Anda menggunakan ini dalam if() pernyataan, nilai yang dikembalikan adalah True nilai. Jika tidak ada nilai yang dikembalikan, maka itu adalah False nilai. Kedua pernyataan berikutnya ini mengevaluasi ke True.

$data = @('red','green','blue')
if ( $data -eq 'green' )
{
    'Green was found'
}
if ( $data -ne 'green' )
{
    'And green was not found'
}

Saya akan mengunjungi kembali ini dalam sesaat ketika kita berbicara tentang pengujian untuk $null.

-match

Operator -match mencoba mencocokkan setiap item dalam koleksi.

PS> $servers = @(
    'LAX-SQL-01'
    'LAX-API-01'
    'ATX-SQL-01'
    'ATX-API-01'
)
PS> $servers -match 'SQL'
LAX-SQL-01
ATX-SQL-01

Saat Anda menggunakan -match dengan satu nilai, variabel $Matches khusus akan diisi dengan info kecocokan. Ini bukan kasus ketika array diproses dengan cara ini.

Kita dapat mengambil pendekatan yang sama dengan Select-String.

$servers | Select-String SQL

Saya melihat lebih dekat pada Select-String,-match dan $matches variabel di posting lain yang disebut Banyak cara untuk menggunakan regex.

$null atau kosong

Pengujian untuk $null atau array kosong bisa menjadi sulit. Berikut adalah perangkap umum dengan array.

Sekilas, pernyataan ini terlihat seperti seharusnya berhasil.

if ( $array -eq $null)
{
    'Array is $null'
}

Tapi aku hanya memeriksa bagaimana -eq memeriksa setiap item dalam array. Jadi kita dapat memiliki array beberapa item dengan nilai $null tunggal dan itu akan mengevaluasi ke $true

$array = @('one',$null,'three')
if ( $array -eq $null)
{
    'I think Array is $null, but I would be wrong'
}

Inilah sebabnya mengapa ini adalah praktik terbaik untuk menempatkan $null di sisi kiri operator. Hal ini menjadikan skenario ini sebagai non-masalah.

if ( $null -eq $array )
{
    'Array actually is $null'
}

Array $null tidak sama dengan array kosong. Jika Anda tahu Anda memiliki array, periksa jumlah objek di dalamnya. Jika array adalah $null, hitungannya adalah 0.

if ( $array.count -gt 0 )
{
    "Array isn't empty"
}

Ada satu jebakan lagi yang harus diwaspadai di sini. Anda dapat menggunakan count bahkan jika Anda memiliki satu objek, kecuali objek tersebut adalah PSCustomObject. Ini adalah bug yang diperbaiki di PowerShell 6.1. Itu kabar baik, tetapi banyak orang masih di 5.1 dan perlu berhati-hati untuk itu.

PS> $object = [PSCustomObject]@{Name='TestObject'}
PS> $object.count
$null

Jika Anda masih menggunakan PowerShell 5.1, Anda dapat membungkus objek dalam array sebelum memeriksa hitungan untuk mendapatkan jumlah yang akurat.

if ( @($array).count -gt 0 )
{
    "Array isn't empty"
}

Untuk sepenuhnya memainkannya dengan aman, periksa $null, lalu periksa hitungannya.

if ( $null -ne $array -and @($array).count -gt 0 )
{
    "Array isn't empty"
}

Semua -eq

Saya baru-baru ini melihat seseorang bertanya bagaimana memverifikasi bahwa setiap nilai dalam array cocok dengan nilai tertentu. Pengguna Reddit /u/bis memiliki solusi cerdas ini yang memeriksa nilai yang salah lalu membalik hasilnya.

$results = Test-Something
if ( -not ( $results -ne 'Passed') )
{
    'All results a Passed'
}

Menambahkan ke array

Pada titik ini, Anda mulai bertanya-tanya cara menambahkan item ke array. Jawaban cepatnya adalah bahwa Anda tidak bisa. Array adalah ukuran tetap dalam memori. Jika Anda perlu menumbuhkannya atau menambahkan satu item ke dalamnya, maka Anda perlu membuat array baru dan menyalin semua nilai dari array lama. Ini terdengar seperti banyak pekerjaan, namun, PowerShell menyembunyikan kompleksitas pembuatan array baru. PowerShell mengimplementasikan operator penambahan (+) untuk array.

Catatan

PowerShell tidak menerapkan operasi pengurangan. Jika Anda menginginkan alternatif yang fleksibel untuk array, Anda perlu menggunakan objek generik List .

Penambahan array

Kita dapat menggunakan operator penambahan dengan array untuk membuat array baru. Jadi mengingat dua array ini:

$first = @(
    'Zero'
    'One'
)
$second = @(
    'Two'
    'Three'
)

Kita dapat menambahkannya bersama-sama untuk mendapatkan array baru.

PS> $first + $second

Zero
One
Two
Three

Plus sama dengan +=

Kita dapat membuat array baru di tempat dan menambahkan item ke dalamnya seperti ini:

$data = @(
    'Zero'
    'One'
    'Two'
    'Three'
)
$data += 'four'

Ingatlah bahwa setiap kali Anda menggunakan += bahwa Anda menduplikasi dan membuat array baru. Ini bukan masalah untuk himpunan data kecil tetapi skalanya sangat buruk.

Penetapan alur

Anda dapat menetapkan hasil alur apa pun ke dalam variabel. Ini adalah array jika berisi beberapa item.

$array = 1..5 | ForEach-Object {
    "ATX-SQL-$PSItem"
}

Biasanya ketika kita berpikir untuk menggunakan alur, kita memikirkan powerShell yang khas satu baris. Kita dapat memanfaatkan alur dengan foreach() pernyataan dan perulangan lainnya. Jadi alih-alih menambahkan item ke array dalam perulangan, kita dapat menjatuhkan item ke alur.

$array = foreach ( $node in (1..5))
{
    "ATX-SQL-$node"
}

Jenis Larik

Secara default, array di PowerShell dibuat sebagai [PSObject[]] jenis. Ini memungkinkannya untuk berisi semua jenis objek atau nilai. Ini berfungsi karena semuanya diwarisi dari PSObject jenis .

Array yang ditik dengan kuat

Anda dapat membuat array dari jenis apa pun menggunakan sintaks yang sama. Saat Anda membuat array yang ditik dengan kuat, array tersebut hanya dapat berisi nilai atau objek jenis yang ditentukan.

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

Menambahkan item ke array adalah salah satu batasan terbesarnya, tetapi ada beberapa koleksi lain yang dapat kita ubah untuk menyelesaikan masalah ini.

ArrayList umumnya adalah salah satu hal pertama yang kita pikirkan ketika kita membutuhkan array yang lebih cepat untuk dikerjakan. Ini bertindak seperti array objek setiap tempat yang kita butuhkan, tetapi menangani penambahan item dengan cepat.

Berikut adalah cara kami membuat ArrayList dan menambahkan item ke dalamnya.

$myarray = [System.Collections.ArrayList]::new()
[void]$myArray.Add('Value')

Kami memanggil ke .NET untuk mendapatkan jenis ini. Dalam hal ini, kami menggunakan konstruktor default untuk membuatnya. Kemudian kita memanggil Add metode untuk menambahkan item ke dalamnya.

Alasan saya menggunakan [void] di awal baris adalah untuk menekan kode pengembalian. Beberapa panggilan .NET melakukan ini dan dapat membuat output yang tidak terduga.

Jika satu-satunya data yang Anda miliki dalam array Anda adalah string, lihat juga menggunakan StringBuilder. Ini hampir sama tetapi memiliki beberapa metode yang hanya untuk berurusan dengan string. dirancang StringBuilder khusus untuk performa.

Adalah umum untuk melihat orang berpindah ke ArrayList dari array. Tetapi datang dari waktu di mana C# tidak memiliki dukungan generik. ArrayList tidak digunakan lagi dalam dukungan untuk generikList[]

Daftar Umum

Jenis generik adalah jenis khusus dalam C# yang mendefinisikan kelas umum dan pengguna menentukan jenis data yang digunakannya saat dibuat. Jadi, jika Anda menginginkan daftar angka atau string, Anda akan menentukan bahwa Anda menginginkan daftar int atau string jenis.

Berikut adalah cara Anda membuat Daftar untuk string.

$mylist = [System.Collections.Generic.List[string]]::new()

Atau daftar untuk angka.

$mylist = [System.Collections.Generic.List[int]]::new()

Kita dapat melemparkan array yang ada ke daftar seperti ini tanpa membuat objek terlebih dahulu:

$mylist = [System.Collections.Generic.List[int]]@(1,2,3)

Kita dapat mempersingkat sintaks dengan using namespace pernyataan di PowerShell 5 dan yang lebih baru. Pernyataan using harus menjadi baris pertama dari skrip Anda. Dengan mendeklarasikan namespace, PowerShell memungkinkan Anda membiarkannya dari jenis data saat Anda mereferensikannya.

using namespace System.Collections.Generic
$myList = [List[int]]@(1,2,3)

Ini membuat jauh List lebih dapat digunakan.

Anda memiliki metode serupa Add yang tersedia untuk Anda. Tidak seperti ArrayList, tidak ada nilai pengembalian pada Add metode sehingga kita tidak perlu melakukannya void .

$myList.Add(10)

Dan kita masih dapat mengakses elemen seperti array lainnya.

PS> $myList[-1]
10

List[PSObject]

Anda dapat memiliki daftar jenis apa pun, tetapi ketika Anda tidak mengetahui jenis objek, Anda dapat menggunakan [List[PSObject]] untuk memuatnya.

$list = [List[PSObject]]::new()

Remove()

ArrayList dan generik List[] keduanya mendukung penghapusan item dari koleksi.

using namespace System.Collections.Generic
$myList = [List[string]]@('Zero','One','Two','Three')
[void]$myList.Remove("Two")
Zero
One
Three

Saat bekerja dengan jenis nilai, itu menghapus yang pertama dari daftar. Anda dapat memanggilnya berulang kali untuk terus menghapus nilai tersebut. Jika Anda memiliki jenis referensi, Anda harus menyediakan objek yang ingin Anda hapus.

[list[System.Management.Automation.PSDriveInfo]]$drives = Get-PSDrive
$drives.remove($drives[2])
$delete = $drives[2]
$drives.remove($delete)

Metode hapus mengembalikan true jika dapat menemukan dan menghapus item dari koleksi.

Koleksi lainnya

Ada banyak koleksi lain yang dapat digunakan tetapi ini adalah pengganti array generik yang baik. Jika Anda tertarik untuk mempelajari lebih lanjut tentang opsi ini, lihat Gist yang disatukan Mark Kraus ini.

Nuansa lainnya

Sekarang setelah saya membahas semua fungsi utama, berikut adalah beberapa hal lagi yang ingin saya sebutkan sebelum saya membungkus ini.

Array praukuran

Saya menyebutkan bahwa Anda tidak dapat mengubah ukuran array setelah dibuat. Kita dapat membuat array dengan ukuran yang telah ditentukan sebelumnya dengan memanggilnya dengan new($size) konstruktor.

$data = [Object[]]::new(4)
$data.count
4

Mengalikan array

Trik kecil yang menarik adalah Anda dapat mengalikan array dengan bilangan bulat.

PS> $data = @('red','green','blue')
PS> $data * 3
red
green
blue
red
green
blue
red
green
blue

Menginisialisasi dengan 0

Skenario umumnya adalah Anda ingin membuat array dengan semua nol. Jika Anda hanya akan memiliki bilangan bulat, array bilangan bulat yang sangat ditik secara default ke semua nol.

PS> [int[]]::new(4)
0
0
0
0

Kita dapat menggunakan trik multiplying untuk melakukan ini juga.

PS> $data = @(0) * 4
PS> $data
0
0
0
0

Hal yang menyenangkan tentang trik mengalikan adalah Anda dapat menggunakan nilai apa pun. Jadi, jika Anda lebih suka memiliki 255 sebagai nilai default Anda, ini akan menjadi cara yang baik untuk melakukannya.

PS> $data = @(255) * 4
PS> $data
255
255
255
255

Array berlapis

Array di dalam array disebut array berlapis. Saya tidak menggunakan ini banyak di PowerShell tetapi saya telah menggunakannya lebih banyak dalam bahasa lain. Pertimbangkan untuk menggunakan array saat data Anda pas dalam pola seperti kisi.

Berikut adalah dua cara kita dapat membuat array dua dimensi.

$data = @(@(1,2,3),@(4,5,6),@(7,8,9))

$data2 = @(
    @(1,2,3),
    @(4,5,6),
    @(7,8,9)
)

Koma sangat penting dalam contoh-contoh tersebut. Saya memberikan contoh sebelumnya dari array normal pada beberapa baris di mana koma bersifat opsional. Itu bukan kasus dengan array multi-dimensi.

Cara kita menggunakan notasi indeks sedikit berubah sekarang karena kita memiliki array berlapis. Dengan menggunakan hal di $data atas, ini adalah bagaimana kita akan mengakses nilai 3.

PS> $outside = 0
PS> $inside = 2
PS> $data[$outside][$inside]
3

Tambahkan sekumpulan tanda kurung untuk setiap tingkat array bersarang. Kumpulan tanda kurung pertama adalah untuk array terluar dan kemudian Anda bekerja dengan cara Anda masuk dari sana.

Write-Output -NoEnumerate

PowerShell suka membongkar atau menghitung array. Ini adalah aspek inti dari cara PowerShell menggunakan alur tetapi ada kalanya Anda tidak ingin hal itu terjadi.

Saya biasanya menyalurkan objek untuk Get-Member mempelajarinya lebih lanjut. Ketika saya menyalurkan array ke dalamnya, array akan dibongkar dan Get-Member melihat anggota array dan bukan array aktual.

PS> $data = @('red','green','blue')
PS> $data | Get-Member
TypeName: System.String
...

Untuk mencegah pembungkusan array tersebut, Anda dapat menggunakan Write-Output -NoEnumerate.

PS> Write-Output -NoEnumerate $data | Get-Member
TypeName: System.Object[]
...

Saya memiliki cara kedua yang lebih dari hack (dan saya mencoba menghindari peretasan seperti ini). Anda dapat menempatkan koma di depan array sebelum Anda menyalurkannya.

PS> ,$data | Get-Member
TypeName: System.Object[]
...

Mengembalikan array

Pembongkaran array ini juga terjadi saat Anda menghasilkan atau mengembalikan nilai dari fungsi. Anda masih bisa mendapatkan array jika Anda menetapkan output ke variabel sehingga ini bukan masalah umum.

Tangkapannya adalah Anda memiliki array baru. Jika itu pernah menjadi masalah, Anda dapat menggunakan Write-Output -NoEnumerate $array atau return ,$array untuk mengatasinya.

Ada lagi?

Saya tahu ini semua banyak untuk mengambil masuk Harapan saya adalah bahwa Anda belajar sesuatu dari artikel ini setiap kali Anda membacanya dan itu ternyata menjadi referensi yang baik untuk Anda untuk waktu yang lama untuk datang. Jika Anda menganggap ini bermanfaat, bagikan dengan orang lain yang menurut Anda mungkin mendapatkan nilai darinya.

Dari sini, saya akan merekomendasikan Anda memeriksa posting serupa yang saya tulis tentang hashtable.