【问题标题】:What is the recommended way for deleting items from a collection?从集合中删除项目的推荐方法是什么?
【发布时间】:2014-10-28 05:48:14
【问题描述】:

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

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

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

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

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

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

【问题讨论】:

标签: powershell collections


【解决方案1】:

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

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

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

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

【讨论】:

  • 嗯,这很优雅,但不适合我的大多数情况,因为大多数时候我真的需要调用执行更多操作的删除操作,而不仅仅是从集合中删除(即从aspx 页面)。
  • 哇!我知道这在某个地方对我隐藏!谢谢你为我揭晓!不错!
【解决方案2】:

我不确定 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);
   }
}

【讨论】:

  • 是的,这正是我遇到的问题。但我的示例与 powershell 中管道的使用有关。我想知道使用原始管道是否有一些解决方案。或者更优雅的东西......
猜你喜欢
  • 2012-02-27
  • 1970-01-01
  • 1970-01-01
  • 2012-10-12
  • 2016-05-26
  • 2020-08-05
  • 2010-09-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多