Array.Add与+ =


178

我在PowerShell数组中发现了一些有趣的行为,即,如果我将数组声明为:

$array = @()

然后尝试使用$array.Add("item")方法向其中添加项目,我收到以下错误:

异常调用带有“ 1”参数的“添加”:“集合的大小固定。”

但是,如果我使用附加项目$array += "item",则该项目将毫无问题地被接受,并且“固定大小”限制似乎并不适用。

为什么是这样?

Answers:


253

使用$array.Add()-method时,您尝试将元素添加到现有数组中。数组是固定大小的集合,因此您将收到一个错误消息,因为它无法扩展。

$array += $element创建一个具有与旧元素+新项目相同的元素的数组,而这个新的较大数组替换$array-variable中的旧元素

您可以使用+ =运算符将元素添加到数组。使用Windows PowerShell时,它实际上使用原始数组的值和添加的值创建一个新数组。例如,要将值200的元素添加到$ a变量的数组中,请输入:

    $a += 200

资料来源:about_Arrays

+= 这是一项昂贵的操作,因此当您需要添加许多项目时,应尝试以尽可能少的操作添加它们,例如:

$arr = 1..3    #Array
$arr += (4..5) #Combine with another array in a single write-operation

$arr.Count
5

如果不可能,请考虑使用效率更高的集合,例如ListArrayList(请参见其他答案)。


谢谢:)认为可能是这样,但是认为在大型阵列中效率低下,因此powershell团队正在做一些不同的事情。
马尔加,

6
没错,使用大型数组会变得效率低下,不幸的是要解决此问题,您必须使用其他类型:powershell.org/wp/2013/09/16/…–
Nacht

3
这取决于。如果要添加和删除很多成员,请尝试ListArrayList。他们会更快。我个人使用+=和排列99%的时间,因为我通常会创建简短的一次性脚本,而多余的秒数并不重要。对于具有大量添加/删除操作的大型脚本,我想在其中进行优化并节省时间,请使用ListArrayList
Frode F.

3
由于数组始终具有固定大小,因此有人知道为什么Add()存在该方法吗?
JohnLBevan '17

4
因为它是从继承的IList。尝试Get-Member -InputObject @()将显示此内容Add Method int IList.Add(System.Object value)
Frode F.

113

如果要动态调整大小的数组,则应列出一个列表。您不仅将获得.Add()功能,而且正如@ frode-f所解释的,动态数组无论如何都具有更高的内存效率和更好的实践。

而且非常容易使用。

代替您的数组声明,请尝试以下操作:

$outItems = New-Object System.Collections.Generic.List[System.Object]

添加项目很简单。

$outItems.Add(1)
$outItems.Add("hi")

而且,如果您在完成时确实想要一个数组,那么也有一个函数。

$outItems.ToArray()

1
我已经试过了。我使用New-Object System.Collections.Generic.List [string]创建它,但是如果我执行.GetType,它告诉我它是一个数组。
Preza8

1
您是否尝试过使用该Add()功能?我可以确认,如果您List如上所述创建通用对象,那么您将拥有一个可变列表,可以使用Add()Remove()方法分别为其添加和删除项。
本德尔最伟大的

1
@ Preza8:(New-Object System.Collections.Generic.List[string]).GetType().Name产量List`1对我来说,符合市场预期; 也许您将其应用于+=包含列表的变量(而不是调用.Add()方法),在这种情况下,变量值确实会转换为数组(System.Object[])。
mklement0 '17

捷径:$a = new-object collections.generic.list[object]
安德鲁(Andrew)

4

+=从循环的输出来看,不使用低效数组而创建数组的最常见习惯是:

$array = foreach($i in 1..10) { 
  $i
}
$array
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.