Array.Tambahkan vs + =

179

Saya telah menemukan beberapa perilaku menarik di PowerShell Array, yaitu, jika saya mendeklarasikan array sebagai:

$array = @()

Dan kemudian mencoba menambahkan item ke sana menggunakan $array.Add("item")metode ini, saya menerima kesalahan berikut:

Panggilan pengecualian "Tambahkan" dengan argumen "1": "Koleksi berukuran tetap."

Namun, jika saya menambahkan item menggunakan $array += "item", item diterima tanpa masalah dan pembatasan "ukuran tetap" tampaknya tidak berlaku.

Kenapa ini?

malgca
sumber

Jawaban:

254

Saat menggunakan $array.Add()-metode, Anda mencoba menambahkan elemen ke dalam array yang ada. Array adalah kumpulan ukuran tetap, jadi Anda akan menerima kesalahan karena tidak bisa diperpanjang.

$array += $elementmenciptakan array baru dengan elemen yang sama dengan yang lama + item baru, dan array yang lebih besar ini menggantikan yang lama di $array-variable

Anda bisa menggunakan operator + = untuk menambahkan elemen ke array. Saat Anda menggunakannya, Windows PowerShell sebenarnya menciptakan array baru dengan nilai-nilai array asli dan nilai tambah. Misalnya, untuk menambahkan elemen dengan nilai 200 ke array di variabel $ a, ketik:

    $a += 200

Sumber: about_Arrays

+= adalah operasi yang mahal, jadi ketika Anda perlu menambahkan banyak item, Anda harus mencoba menambahkannya dalam operasi sesedikit mungkin, mis:

$arr = 1..3    #Array
$arr += (4..5) #Combine with another array in a single write-operation

$arr.Count
5

Jika itu tidak memungkinkan, pertimbangkan untuk menggunakan koleksi yang lebih efisien seperti Listatau ArrayList(lihat jawaban lainnya).

Frode F.
sumber
Terima kasih :) Pikir itu mungkin seperti ini tetapi berpikir itu akan tidak efisien dengan array besar, jadi tim PowerShell melakukan sesuatu yang berbeda.
malgca
6
itu persis benar, itu menjadi tidak efisien dengan array besar, sayangnya untuk menyiasati ini Anda harus menggunakan tipe yang berbeda: powershell.org/wp/2013/09/16/...
Nacht
3
Tergantung. Jika Anda akan menambah dan menghapus banyak anggota maka ya, coba Listatau ArrayList. Mereka akan jauh lebih cepat. Saya pribadi menggunakan +=dan mengatur 99% dari waktu karena saya biasanya membuat skrip membuang-buang pendek di mana detik tambahan tidak masalah. Untuk skrip besar dengan banyak menambahkan / menghapus tempat saya ingin mengoptimalkan dan menghemat waktu saya gunakan Listatau ArrayList.
Frode F.
3
Karena array selalu berukuran tetap, apakah ada yang tahu mengapa Add()metode ini ada?
JohnLBevan
4
Karena itu diwarisi dari IList. Coba Get-Member -InputObject @()akan perlihatkan iniAdd Method int IList.Add(System.Object value)
Frode F.
113

Jika Anda menginginkan array berukuran dinamis, maka Anda harus membuat daftar. Anda tidak hanya akan mendapatkan .Add()fungsionalitasnya, tetapi seperti yang dijelaskan oleh @ frode-f, array dinamis lebih efisien dalam memori dan praktik yang lebih baik.

Dan itu sangat mudah digunakan.

Alih-alih deklarasi array Anda, coba ini:

$outItems = New-Object System.Collections.Generic.List[System.Object]

Menambahkan item sederhana.

$outItems.Add(1)
$outItems.Add("hi")

Dan jika Anda benar-benar menginginkan sebuah array ketika Anda selesai, ada fungsi untuk itu juga.

$outItems.ToArray()
Sebastian Kaczmarek
sumber
1
Saya sudah mencoba ini. Saya membuatnya menggunakan New-Object System.Collections.Generic.List [string] tetapi kemudian jika saya melakukannya .GetType, ia memberi tahu saya itu adalah array.
Preza8
1
Sudahkah Anda mencoba menggunakan Add()fungsinya? Saya dapat mengkonfirmasi, jika Anda membuat Listobjek generik seperti yang dinyatakan di atas, Anda memiliki daftar yang dapat diubah yang dapat Anda tambahkan dan hapus item menggunakan metode Add()dan Remove()masing-masing.
Bender the Greatest
1
@ Preza8: (New-Object System.Collections.Generic.List[string]).GetType().Namehasil List`1untuk saya, seperti yang diharapkan; mungkin Anda menerapkan +=variabel yang berisi daftar (daripada memanggil .Add()metode), dalam hal ini nilai variabel memang akan dikonversi ke array ( System.Object[]).
mklement0
Pintasan:$a = new-object collections.generic.list[object]
Andrew
4

Idiom yang paling umum untuk membuat array tanpa menggunakan inefisien +=adalah sesuatu seperti ini, dari output loop:

$array = foreach($i in 1..10) { 
  $i
}
$array
js2010
sumber