根据条件从列表中删除项目


77

我有一个这样的结构:

public struct stuff
{
    public int ID;
    public int quan;
}

并要删除产品所在的ID位置1。
我目前正在尝试这样做:

prods.Remove(new stuff{ prodID = 1});

而且不起作用。

谢谢大家

Answers:


64

使用linq:

prods.Remove( prods.Single( s => s.ID == 1 ) );

也许您甚至想使用SingleOrDefault()并检查该元素是否根本存在...

编辑:
由于stuff是一个结构,SingleOrDefault()将不会返回null。但是它将返回default(stuff),其ID为0。如果您的普通填充物对象的ID不为0,则可以查询以下ID:

var stuffToRemove = prods.SingleOrDefault( s => s.ID == 1 )
if( stuffToRemove.ID != 0 )
{
    prods.Remove( stuffToRemove );
}

可以肯定的是Remove(null)抛出一个异常,该异常排除了SingleOrDefault所在的位置。
马特·米切尔

1
@Graphain:我为您添加了一个示例
tanascius 2010年

或者可能更具可读性if (stuffToRemove != default(stuff))
Rufus L

207

如果您的集合类型是List<stuff>,则最好的方法可能是以下方法:

prods.RemoveAll(s => s.ID == 1)

这只会对列表进行一次遍历(迭代),因此应该比其他方法更有效。

如果您的类型更一般地是ICollection<T>,则如果您关心性能,可能会写一个简短的扩展方法。如果没有,那么您可能会放弃使用LINQ(调用WhereSingle)。


5
由于IList没有RemoveAll,因此无法接受此答案。主题入门者没有指定他/她拥有什么:List <T>或IList <T>。
Evgeni Nabokov

5
“不能”吗?哈哈。不要学究。即使作者正在使用IList,RemoveAll的实现也很简单。
Noldorin

5

如果您有LINQ:

var itemtoremove = prods.Where(item => item.ID == 1).First();
prods.Remove(itemtoremove)

您可以将where查询作为参数传递给First()
Matt Mitchell,2010年

或者,您也可以替换WhereFirst
Rufus L


0

prods.Remove(prods.Single(p=>p.ID == 1));

正如Vincent建议的那样,您无法在foreach中修改集合


单一会比第一个慢,但它可以确保您没有相同ID的重复产品,这可能是您要检查的东西。
马特·米切尔

0

您只能删除自己引用的内容。因此,您将必须搜索整个列表:

stuff r;
foreach(stuff s in prods) {
  if(s.ID == 1) {
      r = s;
      break;
  }
}
prods.Remove(r);

要么

for(int i = 0; i < prods.Length; i++) {
    if(prods[i].ID == 1) {
        prods.RemoveAt(i);
        break;
    }
}

在列表上使用find或findIndex函数而不是遍历它不是更快吗?
罗布

1
您无法修改要迭代的集合
Matt Mitchell,2010年

@Rob,对于列表,查找应该相同。
马特·米切尔

@Graphain哎呀。@Rob,是的,发现可能更好。
Vincent McNabb

0

对于那些想要使用Entity Framework数据库中删除它的人来说,这是一个解决方案:

prods.RemoveWhere(s => s.ID == 1);

扩展方法本身:

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

PS这模拟RemoveAll()了实体框架的数据库集不可用的方法。


-2

您可以使用Linq。

var prod = from p in prods
           where p.ID != 1
           select p;

这不会删除对象。如果您分配的prods = prods.Where(p != 1).ToList()距离更近,但不会修改列表,则将您作为参数给定。
马特·米切尔
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.