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

时间:2017-03-29 02:10:09

标签: 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
}

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

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

4 个答案:

答案 0 :(得分:9)

在这种情况下使用New-Object

PS> $arr = New-Object 'int[]' 10000; $arr.length
10000

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

PS> $arr = [int[]]::new(10000); $arr.length
10000

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

如果您需要创建"无类型"数组与PowerShell的工作方式相同([System.Object[]]),将object替换为int;例如,[object[]]::new(10000);此类数组的元素将默认为$null 但是,TessellatingHeckler's helpful answer显示了一个非常更简洁的替代方案,甚至允许您将所有元素初始化为特定值

阵列的大小固定;如果需要类似数组的数据结构,您可以预先分配动态增长,请参阅Bluecakes' helpful [System.Collections.ArrayList]-based answer

[System.Collections.ArrayList][System.Object[]]的可调整大小的模拟,其 泛型等效 - 与上面的[int[]]示例一样 - 允许您使用特定类型来提高性能和稳健性(如果可行), [System.Collections.Generic.List[<type>]] ,例如:

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

请注意 - 与[System.Collections.ArrayList]一样 - 指定初始容量10000,此处)不会立即分配内部使用的数组 < / em> - 容量值被简单地存储(并作为属性.Capacity公开),并且当第一个元素被添加到时,按需分配具有该容量的内部数组(内部大小留下增长空间)。清单。

[System.Collections.Generic.List[<type>]]&#39; .Add()方法值得称道的是产生输出,而[System.Collections.ArrayList]&#39; 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()

答案 1 :(得分:4)

PowerShell中你是正确的+=将销毁旧数组并使用新项创建一个新数组。

对于处理大量项目,我强烈建议使用.NET中的ArrayList类型,因为这不是固定大小的数组,因此PowerShell每次添加项目时都不会销毁它对它而且我发现这在我的项目中工作得更好。

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

因此,在您的脚本中,我会像这样创建一个空的ArrayList

[System.Collections.ArrayList]$arr = @()

然后当您需要添加内容时,只需拨打.Add()(您不需要预先填充10000个项目的数组,它会在您添加项目时展开)。

$arr.Add([int]0)

使用ArrayList的示例:

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

答案 2 :(得分:3)

数组文字乘法: $ arr = @($ null)* 10000

答案 3 :(得分:0)

您可以随时执行此操作:

fetch('http://example.com/something').then(data => data.json()).then(initalState => {
    render(
        <Provider store={/*stored created with initalState*/}>
            <App />
        </Provider>,
        document.getElementById('app')
    )
});

这几乎就像你正在做的那样,除非你不必这样做 写出所有的价值观。