Remove item from list based on condition
I have a struct like this:
public struct stuff
{
public int ID;
public int quan;
}
and want to to remove the product wh开发者_开发知识库ere ID
is 1.
prods.Remove(new stuff{ prodID = 1});
and it's not working.
THANKS TO ALL
If your collection type is a List<stuff>
, then the best approach is probably the following:
prods.RemoveAll(s => s.ID == 1)
This only does one pass (iteration) over the list, so should be more efficient than other methods.
If your type is more generically an ICollection<T>
, it might help to write a short extension method if you care about performance. If not, then you'd probably get away with using LINQ (calling Where
or Single
).
Using linq:
prods.Remove( prods.Single( s => s.ID == 1 ) );
Maybe you even want to use SingleOrDefault()
and check if the element exists at all ...
EDIT:
Since stuff
is a struct, SingleOrDefault()
will not return null. But it will return default( stuff ), which will have an ID of 0. When you don't have an ID of 0 for your normal stuff-objects you can query for this ID:
var stuffToRemove = prods.SingleOrDefault( s => s.ID == 1 );
if( stuffToRemove.ID != 0 )
{
prods.Remove( stuffToRemove );
}
If you have LINQ:
var itemtoremove = prods.Where(item => item.ID == 1).First();
prods.Remove(itemtoremove)
prods.Remove(prods.Find(x => x.ID == 1));
Here is a solution for those, who want to remove it from the database with Entity Framework:
prods.RemoveWhere(s => s.ID == 1);
And the extension method itself:
using System;
using System.Linq;
using System.Linq.Expressions;
using Microsoft.EntityFrameworkCore;
namespace LivaNova.NGPDM.Client.Services.Data.Extensions
{
public static class DbSetExtensions
{
public static void RemoveWhere<TEntity>(this DbSet<TEntity> entities, Expression<Func<TEntity, bool>> predicate) where TEntity : class
{
var records = entities
.Where(predicate)
.ToList();
if (records.Count > 0)
entities.RemoveRange(records);
}
}
}
P.S. This simulates the method RemoveAll()
that's not available for DB sets of the entity framework.
prods.Remove(prods.Single(p=>p.ID == 1));
you can't modify collection in foreach, as Vincent suggests
You can only remove something you have a reference to. So you will have to search the entire list:
stuff r;
foreach(stuff s in prods) {
if(s.ID == 1) {
r = s;
break;
}
}
prods.Remove(r);
or
for(int i = 0; i < prods.Length; i++) {
if(prods[i].ID == 1) {
prods.RemoveAt(i);
break;
}
}
A bit late to the game, however, a simple extension method can implement a RemoveAll
on IList<T>
. The trick is to loop over the collection in reverse order to avoid the extra logic of deleting the current item and having to try on the current index if removed. Also the reverse order prevents having to copy all the remaining items. Depending on the .NET version, this copy could be expensive.
public static int RemoveAll<T>(this IList<T> list, Predicate<T> match)
{
if (list == null) throw new ArgumentNullException("list");
if (match == null) throw new ArgumentNullException("match");
int count = 0;
for (int i = list.Count - 1; i >= 0; i--)
{
if (match(list[i]))
{
++count;
list.RemoveAt(i);
}
}
return count;
}
You could use Linq.
var prod = from p in prods
where p.ID != 1
select p;
精彩评论