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?

+5


source to share


4 answers


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

      

+8


source


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

      

+4


source


Mass multiplying an array:

$arr = @($null) * 10000

      

+3


source


You can always do this:

$a = @(0..9999)
$a.length

      

This is similar to what you are already doing, except that you do not need to write out all the values.

0


source







All Articles