5

アイテムを使用から削除する一般的なリストがありList.Remove(Object)ます。アイテムを削除していましたが、5 番目のアイテムに到達するたびに削除に失敗し、リストから削除されません。何を削除するかは問題ではないようですが、5 つのアイテムを削除しようとするたびに、5 番目のアイテムで失敗します。

何が原因でしょうか? のドキュメントを見るとList(Of T).Remove、アイテムを削除するために使用しているアルゴリズムが指定されていません。

4

5 に答える 5

12

Removeオブジェクトの呼び出しに基づいて一致.Equalsします。特定のオブジェクトのデフォルトでは、同じオブジェクトにのみ一致します。同じオブジェクトでなくても、同じプロパティを持つ 2 つのオブジェクトを等しいと見なしたい場合は、Equalsメソッドをオーバーライドして、そこにロジックを配置する必要があります。

ただし、別の適切なオプションはRemoveAll、匿名のデリゲートまたはラムダ式を探している基準と共に使用して渡すことです。例えば:

customers.RemoveAll(customer => customer.LastName.Equals(myCustomer.LastName));

もちろん、一致するすべてのアイテムを本当に削除したい場合、および/または一致するアイテムが1つしかないことが確実な場合にのみ機能します。

于 2009-12-17T18:42:57.647 に答える
2

インデックス ベースの方法を使用してリストから項目を削除する場合、削除する項目の後の項目のインデックスは、その前の項目を削除すると -1 ずつ変化することに注意してください。

于 2009-12-17T16:42:08.520 に答える
0

原則として、ループしているコレクションは変更しないでください。そのコレクション内の項目のみを変更してください。for each ループ内のアイテムを削除する際の問題は、ループされているコレクションが変更され、リストの数と反復の場所が妨げられることです。

一般的な解決策は次のとおりです。

  1. イテレータとの干渉が実行に影響を与えないように、コレクションを逆方向にループします。
  2. 新しいコレクションを作成して、1 つのコレクションを変更し、別のコレクションをループできるようにします。

逆方向にループ:

a を受け取る拡張メソッドを次に示しますCollection(Of T)( a を使用することもできますが、リスト クラスは、基本的にこれと同じことをList(Of T)行うメソッドを既に公開しています)。 逆方向にループし、渡されたラムダ関数に基づいて、コレクション内の各アイテムの有効性を確認します。一致する場合は、削除します。RemoveAll

<Extension()>
Public Sub RemoveEach(Of T)(ByRef col As Collection(Of T),
                            ByVal match As Func(Of T, Boolean))
    For i = col.Count - 1 To 0 Step -1
        If match(col(i)) Then col.RemoveAt(i)
    Next
End Sub

次に、次のように使用します。

Dim col = New Collection(Of Integer)({1, 2, 3, 4}.ToList)
col.RemoveEach(Function(i) (i Mod 2) = 0)
'Produces list of 1 & 3

新しいコレクションを作成:

コレクション インデックスを追跡し、アイテムを削除するRemoveAt代わりにRemove、オブジェクトを受け取り、コレクションの残りの部分がそのオブジェクトと一致するかどうかをチェックする方が効率的です。ただし、For ループ内でアイテムの削除を処理する方法が本当に必要な場合はToList、元のコレクションを呼び出して、新しいリストを作成することができます。次に、新しいリストをループして、元のリストから削除する必要があるアイテムを見つけることができます。オブジェクトが見つかったら、元のコレクションから安全に削除できます。これは、現在列挙されていないためです。

<Extension()>
Public Sub RemoveEachObject(Of T)(ByRef col As Collection(Of T), 
                                  ByVal match As Func(Of T, Boolean))
    For Each o As T In col.ToList()
        If match(o) Then col.Remove(o)
    Next
End Sub

詳細については、「foreach」ループ内のリストから削除するこの素晴らしい回答を確認してください。

于 2014-03-03T15:40:45.547 に答える
0

あなたのリストにはいくつのアイテムがありますか? ループするだけで、どうやってそれらを削除していますか?これらは 0 ベースのリストであることに注意してください。整数を使用して何らかの種類の For ループを実行している場合、項目を削除しているため機能しない場合があります。

于 2009-12-17T16:39:12.513 に答える
-1

for ループを使用して要素を削除する場合は、foreach の使用を検討する必要があります。コレクション、リスト、および数値化可能なオブジェクトにより適しています。

于 2009-12-17T16:42:03.990 に答える