从集合中删除项目的推荐方法是什么?

时间:2012-09-17 10:42:48

标签: powershell collections

我经常需要根据某些条件从一个集合中删除一些对象,每次我都用它来删除:

Get-SomeCollection | ? { $_.SomeProperty -eq "SomeValue" } | % { $_.Delete() }

但是这将只删除第一个元素,然后抛出异常“Collection was modified ... bla bla ...”。我明白了这一点,但这样做的推荐方法是什么?

我通常使用一些数组itemsToDelete,然后我再次遍历该数组并执行删除操作:

$itemsToDelete = @()
Get-SomeCollection | ? { $_.SomeProperty -eq "SomeValue" } | % { $itemsToDelete += $_ }
$itemsToDelete | % { $_.Delete() }

我想知道这是足够好还是更好的方式。

2 个答案:

答案 0 :(得分:4)

您通常会使用过滤器来实际过滤项目。因此,您不要修改原始集合,而只是过滤掉您感兴趣的集合。

Get-SomeCollection | ? { $_.SomeProperty -ne "SomeValue" }

如果您需要对要删除的项目调用操作,则只需创建已过滤集合的副本并枚举该过滤集合即可。这样做非常简单,因为您只需要将表达式括在parantheses中,以便在使用以下命令运行枚举之前对其进行求值:

 (Get-SomeCollection | ? { $_.SomeProperty -eq "SomeValue" }) | % { $_.Delete() }

答案 1 :(得分:0)

我不确定powershell的语法,但.NET中的简单foreach语句存在此问题

解决方案是在for循环中向后迭代。

而不是:

foreach(var item in collection)
{
   if(condition)
   {
      collection.Remove(item); //exception!
   }
}
你这样做:

for(int count = collection.Count - 1; count > 0; count--)
{
   var currentItem = collection[count];
   if(condition)
   {
      collection.RemoveAt(count);
   }
}