リストを繰り返し処理しながら、リストでRemove
or RemoveAt
を使用することは、ほとんど常に間違っていることであるため、意図的に難しくなっています。巧妙なトリックで機能させることができるかもしれませんが、非常に遅くなります。呼び出すたびにRemove
、リスト全体をスキャンして、削除する要素を見つける必要があります。呼び出すたびRemoveAt
に、後続の要素を1ポジション左に移動する必要があります。そのため、Remove
またはを使用するソリューションRemoveAt
では、2次時間O(n²)が必要になります。
RemoveAll
可能であれば使用してください。それ以外の場合、次のパターンは、リストをインプレースで線形時間O(n)でフィルターします。
// Create a list to be filtered
IList<int> elements = new List<int>(new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10});
// Filter the list
int kept = 0;
for (int i = 0; i < elements.Count; i++) {
// Test whether this is an element that we want to keep.
if (elements[i] % 3 > 0) {
// Add it to the list of kept elements.
elements[kept] = elements[i];
kept++;
}
}
// Unfortunately IList has no Resize method. So instead we
// remove the last element of the list until: elements.Count == kept.
while (kept < elements.Count) elements.RemoveAt(elements.Count-1);