Creating array with large initial size in powershell
The only way to create an array in powershell is
$arr = @(1, 2, 3)
However, this creation method is not convenient if I want to create an array with a large initial size, such as 10000.
Because I don't want to write code like this
$arr = @(0, 0, 0, 0, 0, 0, ... ,0) # 10000 0s in this line of code
Writing code like the one below is inefficient.
$arr = @()
for ($i = 1; $i -le 10000; $i++) {
$arr += 0
}
Because whenever the statement is executed +=
, all the elements of the old array will be copied to the newly created array.
What's the best way to create an array with a large initial size in powershell?
source to share
Use New-Object
in this case:
PS> $arr = New-Object 'int[]' 10000; $arr.length
10000
Or in PSv5 + using a static method new()
for the type:
PS> $arr = [int[]]::new(10000); $arr.length
10000
These commands create a strongly typed array using the base type [int]
in this example. If the use case allows it, it is preferred for performance and type safety reasons.
If you need to create an "untyped" array just like PowerShell ( [System.Object[]]
) does , replace object
with int
; for example [object[]]::new(10000)
; the elements of such an array will be equal by default $null
.
However, TessellatingHeckler's helpful answer shows a much more concise alternative that even allows all elements to be initialized to a specific value .
Arrays are of fixed size; if you need an array-like data structure that can be pre-allocated and dynamically grown , see Bluecakes [System.Collections.ArrayList]
-based's helpful answer .
[System.Collections.ArrayList]
is a [System.Object[]]
mutable counterpart [System.Object[]]
, and its generic equivalent - which, like the example [int[]]
above, allows you to use a specific type for performance and reliability (if possible)) is , for example: [System.Collections.Generic.List[<type>]]
PS> $lst = [System.Collections.Generic.List[int]]::New(10000); $lst.Capacity
10000
Note that - as is the case [System.Collections.ArrayList]
- specifying the initial capacity (here 10000
) does not allocate an internally used array with that size right away - the capacity value is simply stored (and .Capacity
as a property .Capacity
), and an internal array with that capacity (an internal size that leaves room for growth) is allocated on demand when the first item is added to the list.
The method [System.Collections.Generic.List[<type>]]
.Add()
does not commendably produce output, whereas the method [System.Collections.ArrayList]
(returns the index of the element just added).
PS> $al = [System.Collections.ArrayList]::new(); $al.Add('first elem')
0 # .Add() outputs the index of the newly added item
# Simplest way to suppress this output:
PS> $null = $al.Add('first elem')
# NO output.
PS> $gl = [System.Collections.Generic.List[string]]::new(); $gl.Add('first elem')
# NO output from .Add()
source to share
As PowerShell
you are right that the +=
destroy the old array and creates a new array with the new elements.
For working with a large set of elements, I would highly recommend using a type ArrayList
from .NET as it is not a fixed size array, so PowerShell
it will not destroy it every time you add an element to it, and I "I found this works better in my projects.
Using it ArrayList
also means you don't have to start with 10,000 items. Since PowerShell
you won't have to re-create your array every time, you can start at 0 and then add each element as needed, rather than starting at 10000.
So, in your script, I will create an empty ArrayList
one like
[System.Collections.ArrayList]$arr = @()
and then when you need to add something to it, just call .Add()
(you don't need to pre-populate the array with 10000 elements, it will expand as you add elements).
$arr.Add([int]0)
Example using ArrayList
:
[System.Collections.ArrayList]$arr = @()
for ($i = 1; $i -le 10000; $i++) {
$arr.Add([int]0)
}
source to share