3

我经常需要根据某些条件从集合中删除一些对象,并且每次我都需要这样做:

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

但这只会删除第一个元素,然后抛出异常“集合已修改......bla bla......”。我明白了例外的意义,但是推荐的方法是什么?

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

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

我想知道这是否足够好或者更好的方法是什么。

4

2 回答 2

4

您通常会使用过滤器从集合中实际过滤项目。因此,您无需修改​​原始集合,而只需过滤掉您感兴趣的那些。

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

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

 (Get-SomeCollection | ? { $_.SomeProperty -eq "SomeValue" }) | % { $_.Delete() }
于 2012-09-17T11:38:33.643 回答
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);
   }
}
于 2012-09-17T11:42:05.857 回答