简体   繁体   中英

How to remove item from list in C#?

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?

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);

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" },   // results[0]
    new myClass { ID=2, FirstName="John", LastName="Wilson" },  // results[1]
    new myClass { ID=3, FirstName="Doug", LastName="Berg" },    // results[2]
    new myClass { ID=4, FirstName="Bill", LastName="Wilson" }   // results[3]
};

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.

A last thing to mention is that lists have an indexer, that is, they can also be accessed like a dynamic array, ie results[3] will give you the 4th element in the results list (because the first element has the index 0, the 2nd has index 1 etc).

So if you want to remove all entries where the first name is the same as in the 4th element of the results list, you can simply do it this way:

results.RemoveAll(r => results[3].FirstName == r.FirstName);

Note that afterwards, only John and Doug will remain in the list, Bill is removed (the first and last element in the example). Important is that the list will shrink automatically, so it has only 2 elements left - and hence the largest allowed index after executing RemoveAll in this example is 1
(which is results.Count() - 1 ).

Some Trivia: You can use this knowledge and create a local function

void myRemove()  { var last = results.Count() - 1; 
                   results.RemoveAll(r => results[last].FirstName == r.FirstName); }

What do you think will happen, if you call this function twice? Like

myRemove(); myRemove(); 

The first call will remove Bill at the first and last position, the second call will remove Doug and only John Wilson remains in the list.


Note: Since C# Version 8 , you can as well write results[^1] instead of var last = results.Count() - 1; and results[last] :

void myRemove()  =>  results.RemoveAll(r => results[^1].FirstName == r.FirstName); 

So you would not need the local variable last anymore (see indices and ranges ). Furthermore, since it is a one-liner, you don't require the curly braces and can use => instead. For a list of all the new features in C#, look here .


DotNetFiddle: Run the demo

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();

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);

More simplified:

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

there is no needing to create a new var object.

Try this code:

resultlist.Remove(resultlist.Find(x => x.ID == 2));

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.

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

{
    class Program
    {
        public static List<Product> list;
        static void Main(string[] args)
        {

            list = new List<Product>() { new Product() { ProductId=1, Name="Nike 12N0",Brand="Nike",Price=12000,Quantity=50},
                 new Product() { ProductId =2, Name = "Puma 560K", Brand = "Puma", Price = 120000, Quantity = 55 },
                 new Product() { ProductId=3, Name="WoodLand V2",Brand="WoodLand",Price=21020,Quantity=25},
                 new Product() { ProductId=4, Name="Adidas S52",Brand="Adidas",Price=20000,Quantity=35},
                 new Product() { ProductId=5, Name="Rebook SPEED2O",Brand="Rebook",Price=1200,Quantity=15}};


            Console.WriteLine("Enter ProductID to remove");
            int uno = Convert.ToInt32(Console.ReadLine());
            var itemToRemove = list.Find(r => r.ProductId == uno);
            if (itemToRemove != null)
                list.Remove(itemToRemove);
            Console.WriteLine($"{itemToRemove.ProductId}{itemToRemove.Name}{itemToRemove.Brand}{itemToRemove.Price}{ itemToRemove.Quantity}");
            Console.WriteLine("------------sucessfully Removed---------------");

            var query2 = from x in list select x;
            foreach (var item in query2)
            {
                /*Console.WriteLine(item.ProductId+" "+item.Name+" "+item.Brand+" "+item.Price+" "+item.Quantity );*/
                Console.WriteLine($"{item.ProductId}{item.Name}{item.Brand}{item.Price}{ item.Quantity}");
            }

        }

    }
}

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