在PowerShell中创建一个初始大小较大的数组

Bri*_*ian 6 powershell

我知道在PowerShell中创建数组的唯一方法是

$arr = @(1, 2, 3)

但是,如果我想创建一个初始大小较大的数组(如10000),则此创建方法不方便.

因为我不想写这样的代码

$arr = @(0, 0, 0, 0, 0, 0, ... ,0) # 10000 0s in this line of code

编写如下代码效率不高.

$arr = @()
for ($i = 1; $i -le 10000; $i++) {
  $arr += 0
}
Run Code Online (Sandbox Code Playgroud)

因为无论何时+=执行运算符,旧数组中的所有元素都将被复制到新创建的数组中.

在PowerShell中创建具有大初始大小的数组的最佳方法是什么?

mkl*_*nt0 14

New-Object在这种情况下使用:

PS> $arr = New-Object 'int[]' 10000; $arr.length
10000
Run Code Online (Sandbox Code Playgroud)

或者,在PSv5 +中,使用new()类型的静态方法:

PS> $arr = [int[]]::new(10000); $arr.length
10000
Run Code Online (Sandbox Code Playgroud)

这些命令在此示例中使用基类型创建强类型数组[int].如果用例允许,出于性能和类型安全的原因,这是优选的.

如果你需要创建一个"类型化"阵列相同的方式,PowerShell将([System.Object[]]),替代objectint; 例如,[object[]]::new(10000); 这样一个数组的元素将默认为$null.然而,
TessellatingHeckler的有用答案显示了一个更简洁的替代方案,甚至允许您将所有元素初始化为特定值.


数组具有固定的大小; 如果你需要一个可以预先分配动态增长的类似数组的数据结构,请参阅Bluecakes的有用[System.Collections.ArrayList]答案.

[System.Collections.ArrayList]是可调整大小的模拟[System.Object[]],它的通用等价物 - 就像[int[]]上面的例子一样- 允许你使用特定的类型来提高性能和稳健性(如果可行的话)[System.Collections.Generic.List[<type>]],例如:

PS> $lst = [System.Collections.Generic.List[int]]::New(10000); $lst.Capacity
10000
Run Code Online (Sandbox Code Playgroud)

需要注意的是-与[System.Collections.ArrayList]-指定初始容量(10000这里)不分配与尺寸的内部使用阵列马上 -电容值被简单地存储(和暴露为属性.Capacity),和一个内部阵列与容量(内部尺寸当第一个元素添加到列表中时,按需分配"留下增长空间".

[System.Collections.Generic.List[<type>]].Add()方法值得称道的是不会产生输出,而[System.Collections.ArrayList]'s会这样做(它会返回刚刚添加的元素的索引).

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()
Run Code Online (Sandbox Code Playgroud)


Tes*_*ler 13

数组字面量乘法:

$arr = @($null) * 10000
Run Code Online (Sandbox Code Playgroud)


Blu*_*kes 6

PowerShell你在正确+=会破坏旧的阵列,并创建一个新项目的新数组。

为了处理大量项目,我强烈建议使用ArrayList.NET 中的类型,因为这不是固定大小的数组,因此PowerShell每次向其中添加项目时都不会破坏它,我发现这在我的工作中效果更好项目。

使用ArrayList也意味着您不需要从 10000 个项目开始。因为PowerShell不需要每次都重新创建数组,所以您可以从 0 开始,然后根据需要添加每个项目,而不是从 10000 开始。

所以在你的脚本中,我会ArrayList像这样创建一个空的

[System.Collections.ArrayList]$arr = @()
Run Code Online (Sandbox Code Playgroud)

然后当你需要向它添加一些东西时,只需调用.Add()(你不需要用 10000 个项目预先填充数组,它会随着你添加项目而扩展)。

$arr.Add([int]0)
Run Code Online (Sandbox Code Playgroud)

您使用的示例ArrayList

[System.Collections.ArrayList]$arr = @()
for ($i = 1; $i -le 10000; $i++) {
    $arr.Add([int]0)
}
Run Code Online (Sandbox Code Playgroud)