How to remove item from list in C#?

Go To StackoverFlow.com

127

I have a list stored in resultlist as follows:

var resultlist = results.ToList();

It looks something like this:

ID FirstName  LastName
-- ---------  --------
1  Bill       Smith
2  John       Wilson
3  Doug       Berg

How do I remove ID 2 from the list?

2012-04-04 20:44
by Nate Pet


258

List<T> has two methods you can use.

RemoveAt(int index) can be used if you know the index of the item. For example:

resultlist.RemoveAt(1);

Or you can use Remove(T item):

var itemToRemove = resultlist.Single(r => r.Id == 2);
resultList.Remove(itemToRemove);

When you are not sure the item really exists you can use SingleOrDefault. SingleOrDefault will return null if there is no item (Single will throw an exception when it can't find the item). Both will throw when there is a duplicate value (two items with the same id).

var itemToRemove = resultlist.SingleOrDefault(r => r.Id == 2);
if (itemToRemove != null)
    resultList.Remove(itemToRemove);
2012-04-04 20:47
by Wouter de Kort
well, than maybe var itemsToRemove = resultlist.Where(r => r.Id == 2); foreach (var itemToRemove in ItemsToRemove) resultList.Remove(itemToRemove);Vlad 2012-04-04 20:51
Shouldn't this be resultlist.Items.RemoveAt(1); - DreamTeK 2016-10-17 08:57


35

resultList = results.Where(x=>x.Id != 2).ToList();

There's a little Linq helper I like that's easy to implement and can make queries with "where not" conditions a little easier to read:

public static IEnumerable<T> ExceptWhere<T>(this IEnumerable<T> source, Predicate<T> predicate)
{
    return source.Where(x=>!predicate(x));
}

//usage in above situation
resultList = results.ExceptWhere(x=>x.Id == 2).ToList();
2012-04-04 20:45
by KeithS
Another similar approach (that uses a predicate) is to use List.FindIndex/List.RemoteAt (which has the "nice" or "not so nice" feature of being a mutating operation) - NoName 2012-04-04 20:50
True, but be careful about saying that List's operation is mutating. List uses an array behind the scenes, and it can recreate its array with a smaller or larger capacity when it thinks that's necessary. Usually, removal is an in-place mutation of the existing array - KeithS 2012-04-04 21:09
This isnt thread safe, and for its simplicity you can just use SingleOrDefault, it doesnt need to be contained in a static metho - NoName 2013-08-27 20:08
Nobody said it was thread-safe (and whether it is depends on what the threads are supposed to be doing; it may in fact be preferable to give a different in-memory construct to a worker thread versus letting them all work on one concurrent collection), and the OP wants all records except the one matching the predicate, so SingleOrDefault would in fact return exactly what they don't want. The "static method" is in fact an extension method, like most of Linq, and it works whenever what you don't want (one element or many) is easier to define than what you do - KeithS 2013-08-27 22:44


22

Short answer:
Remove (from list results)

results.RemoveAll(r => r.ID == 2); will remove the item with ID 2 in results (in place).

Filter (without removing from original list results):

var filtered = result.Where(f => f.ID != 2); returns all items except the one with ID 2

Detailed answer:

I think .RemoveAll() is very flexible, because you can have a list of item IDs which you want to remove - please regard the following example.

If you have:

class myClass {
    public int ID; public string FirstName; public string LastName;
}

and assigned some values to results as follows:

var results=new List<myClass> {
    new myClass()  { ID=1, FirstName="Bill", LastName="Smith" },
    new myClass()  { ID=2, FirstName="John", LastName="Wilson" },
    new myClass()  { ID=3, FirstName="Doug", LastName="Berg" },
    new myClass()  { ID=4, FirstName="Bill", LastName="Wilson" },
};

Then you can define a list of IDs to remove:

var removeList = new List<int>() { 2, 3 };

And simply use this to remove them:

results.RemoveAll(r => removeList.Any(a => a==r.ID));

It will remove the items 2 and 3 and keep the items 1 and 4 - as specified by the removeList. Note that this happens in place, so there is no additional assigment required.

Of course, you can also use it on single items like:

results.RemoveAll(r => r.ID==4);

where it will remove Bill with ID 4 in our example.


DotNetFiddle: Run the demo

2016-02-15 14:50
by Matt


4

There is another approach. It uses List.FindIndex and List.RemoveAt.

While I would probably use the solution presented by KeithS (just the simple Where/ToList) this approach differs in that it mutates the original list object. This can be a good (or a bad) "feature" depending upon expectations.

In any case, the FindIndex (coupled with a guard) ensures the RemoveAt will be correct if there are gaps in the IDs or the ordering is wrong, etc, and using RemoveAt (vs Remove) avoids a second O(n) search through the list.

Here is a LINQPad snippet:

var list = new List<int> { 1, 3, 2 };
var index = list.FindIndex(i => i == 2); // like Where/Single
if (index >= 0) {   // ensure item found
    list.RemoveAt(index);
}
list.Dump();        // results -> 1, 3

Happy coding.

2012-04-04 21:00
by NoName


3

You don't specify what kind of list, but the generic List can use either the RemoveAt(index) method, or the Remove(obj) method:

// Remove(obj)
var item = resultList.Single(x => x.Id == 2);
resultList.Remove(item);

// RemoveAt(index)
resultList.RemoveAt(1);
2012-04-04 20:49
by mgnoonan


3

More simplified:

resultList.Remove(resultList.Single(x => x.Id == 2));

there is no needing to create a new var object.

2016-05-06 20:08
by Javier Andres Caicedo


0

... or just resultlist.RemoveAt(1) if you know exactly the index.

2012-04-04 20:46
by Vlad
only if it's sorted by ID - zzzzBov 2012-04-04 20:47
Ads