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 に答える