简体   繁体   中英

Deleting item from a List<Type>

This is how I remove an item from a List . Is this the right way? Is there any cleaner/faster way to achieve this.

List<ItemClass> itemsToErase = new List<ItemClass>();
foreach(ItemClass itm in DS)
{
       if(itm.ToBeRemoved)
            itemsToErase .Add(itm);
}
foreach(ItemClass eraseItem in itemsToErase)
{
      DS.Remove(eraseItem );
}      

EDIT: DS is of type List<ItemClass>

EDIT: Have one more doubt. What if DS is a LinkedList<ItemClass> . There is no RemoveAll() for that.

There is List.RemoveAll() which takes a delegate where you can add your comparison function.

Eg:

List<ItemClass> itemsToErase = new List<ItemClass>();
itemsToErase.RemoveAll( itm => itm.ToBeRemoved );

Not really, the logic remains the same no matter how you do it. You cannot iterate over and modify a collection at the same time. It looks cleaner with LINQ:

var list = new List<int> { 1, 2, 3, 4, 5 };
var except = new List<int> { 3, 4 };
var result = list.Except(except);

Hope this helps.

edit: Even list.RemoveAll(...) has to maintain two lists internally to do it.

edit2: Actually svick is right; after looking at the implementation, RemoveAll is fastest.

You can use the RemoveAll() method :

DS.RemoveAll(x => x.ToBeRemoved);

This is a O(n) operation, your code is O(n^2).

This methods avoids a lot of copies in the orginal List but has a greater memory consumption.

List<ItemClass> newList = new List<ItemClass>(originalList.Count);

foreach(var item in originalList) {
    if (!item.ToBeRemoved) 
        newList.Add(item);
}

originalList = newList;

使用这种方法

 DS.RemoveAll(x => x.ToBeRemoved); 

Your code is a common solution to the problem and is fine. Especially if there are only a few items to be removed.
As others have suggested you can also create a new list containing the items you want to keep and then discard the old list. This works better if most items are going to be removed and only a small number kept. When picking either of these methods keep in mind that both require the allocation of a new list object. This extra memory allocation probably isn't an issue but might be, depending on what the rest of the code is doing.
As others have mentioned there is also the RemoveAll method. This is what I would use, it is neat, clear and as efficient as anything using a list can be.
The last option is to use an index to loop through the collection. EG.
(Sorry for the VB, I use it more often than C# and didn't want to confuse by getting the syntax wrong)

Dim i as Integer
Do While i<DS.Count
If DS.Item(i).ToBeRemoved Then
DS.RemoveAt(i)
Else
i+=1
End If
Loop

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM