Solución:
Usar New-Object
en este caso:
PS> $arr = New-Object int[] 10000; $arr.length
10000
O, en PSv5 +, usando la estática new()
método en el tipo:
PS> $arr = [int[]]::new(10000); $arr.length
10000
Estos comandos crean un matriz fuertemente tipada, usando el tipo base [int]
en este ejemplo. Si el caso de uso lo permite, es preferible por razones de rendimiento y seguridad del tipo.
Si lo necesitas crear una matriz “sin tipo” de la misma manera que lo hace PowerShell ([System.Object[]]
), sustituto object
por int
; p.ej, [object[]]::new(10000)
; los elementos de dicha matriz se establecerán por defecto en $null
.
Tessellates La útil respuesta de Heckler, sin embargo, muestra mucho mas conciso alternativa que incluso te permite inicializar todos los elementos a un valor específico.
Las matrices tienen un tamaño fijo; si tu necesita una estructura de datos similar a una matriz que pueda preasignar y crecer dinámicamente, vea la ayuda de Bluecakes [System.Collections.ArrayList]
-respuesta basada.
[System.Collections.ArrayList]
es el análogo de tamaño variable para [System.Object[]]
, y es genérico equivalente – que como el [int[]]
ejemplo anterior – le permite utilizar una específico escribe para el rendimiento y la robustez (si es factible), es [System.Collections.Generic.List[<type>]]
, p.ej:
PS> $lst = [System.Collections.Generic.List[int]]::New(10000); $lst.Capacity
10000
Tenga en cuenta que, al igual que con [System.Collections.ArrayList]
– especificando un capacidad inicial (10000
, aquí) no asigna la matriz utilizada internamente con ese tamaño inmediatamente – el valor de la capacidad simplemente se almacena (y se expone como propiedad .Capacity
), y una matriz interna con esa capacidad (tamaño interno que deja espacio para el crecimiento) se asigna bajo demanda, cuando se agrega el primer elemento a la lista.
[System.Collections.Generic.List[<type>]]
‘s .Add()
el método lo hace encomiablemente no producir salida, mientras que [System.Collections.ArrayList]
hace (devuelve el índice del elemento que se acaba de agregar).
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()
En PowerShell
tienes razón en eso +=
destruirá la matriz anterior y creará una nueva matriz con los nuevos elementos.
Para trabajar con una gran colección de elementos, recomiendo encarecidamente utilizar el ArrayList
escriba desde .NET ya que esta no es una matriz de tamaño fijo, por lo que PowerShell
no lo destruirá cada vez que le agregue un elemento y he descubierto que esto funciona mejor en mis proyectos.
Utilizando ArrayList
también significa que no es necesario comenzar con 10000 elementos. Porque PowerShell
no necesitará recrear su matriz cada vez, puede comenzar con 0 y luego agregar cada elemento según sea necesario en lugar de comenzar con 10000.
Entonces, en tu script, crearía un vacío ArrayList
al igual que
[System.Collections.ArrayList]$arr = @()
y luego, cuando necesite agregar algo, simplemente llame .Add()
(No es necesario rellenar previamente la matriz con 10000 elementos, se expandirá a medida que agregue elementos).
$arr.Add([int]0)
Tu ejemplo usando un ArrayList
:
[System.Collections.ArrayList]$arr = @()
for ($i = 1; $i -le 10000; $i++) {
$arr.Add([int]0)
}
Matriz de multiplicación literal:
$arr = @($null) * 10000