Remove an item from an IEnumerable<T> collection

I have a popuplated IEnumerable<User> collection.

I want to remove an item from it, how can I do this?

foreach(var u in users)
{
if(u.userId = 1123)
{
// remove!
}
}

I know your not suppose to remove while looping, so I don't mind either creating a new collection or removing it after.

But I don't know how to remove an item, kind of lost for some reason on this!

Alternately which I am confused on also, how can I create a new collection like:

IEnumerable<User> modifiedUsers = new List<User>();


foreach(var u in users)
{
if(u.userId != 1233)
{
modifiedUsers.add ??????
}
}

How can I add to the collection?

169295 次浏览

You can't. IEnumerable<T> can only be iterated.

In your second example, you can remove from original collection by iterating over a copy of it

foreach(var u in users.ToArray()) // ToArray creates a copy
{
if(u.userId != 1233)
{
users.Remove(u);
}
}

You can not remove an item from an IEnumerable; it can only be enumerated, as described here: http://msdn.microsoft.com/en-us/library/system.collections.ienumerable.aspx

You have to use an ICollection if you want to add and remove items. Maybe you can try and casting your IEnumerable; this will off course only work if the underlying object implements ICollection`.

See here for more on ICollection: http://msdn.microsoft.com/en-us/library/92t2ye13.aspx

You can, of course, just create a new list from your IEnumerable, as pointed out by lante, but this might be "sub optimal", depending on your actual use case, of course.

ICollection is probably the way to go.

Try turning the IEnumerable into a List. From this point on you will be able to use List's Remove method to remove items.

To pass it as a param to the Remove method using Linq you can get the item by the following methods:

  • users.Single(x => x.userId == 1123)
  • users.First(x => x.userId == 1123)

The code is as follows:

users = users.ToList(); // Get IEnumerable as List


users.Remove(users.First(x => x.userId == 1123)); // Remove item


// Finished

Not removing but creating a new List without that element with LINQ:

// remove
users = users.Where(u => u.userId != 123).ToList();


// new list
var modified = users.Where(u => u.userId == 123).ToList();

The IEnumerable interface is just that, enumerable - it doesn't provide any methods to Add or Remove or modify the list at all.

The interface just provides a way to iterate over some items - most implementations that require enumeration will implement IEnumerable such as List<T>

Why don't you just use your code without the implicit cast to IEnumerable

// Treat this like a list, not an enumerable
List<User> modifiedUsers = new List<User>();


foreach(var u in users)
{
if(u.userId != 1233)
{
// Use List<T>.Add
modifiedUsers.Add(u);
}
}

You can't remove IEnumerable<T> elements, but you can use the Enumerable.Skip Method

There is now an extension method to convert the IEnumerable<> to a Dictionary<,> which then has a Remove method.

public readonly IEnumerable<User> Users = new User[]; // or however this would be initialized


// To take an item out of the collection
Users.ToDictionary(u => u.Id).Remove(1123);


// To take add an item to the collection
Users.ToList().Add(newuser);

You can do something like this:

users = users.Where(x => x.userId != userIdToRemove);

users.toList().RemoveAll(user => <your condition>)