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

w6lpcovy  于 2022-12-15  发布在  其他
关注(0)|答案(9)|浏览(198)

我有一个这样的结构体:

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

并且想要移除ID为1的乘积。
我正在尝试此操作:

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

但没有用。

感谢所有人

odopli94

odopli941#

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

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

这只在列表上执行一次传递(迭代),因此应该比其他方法更有效。
如果你的类型是ICollection<T>,如果你关心性能的话,写一个短的扩展方法可能会有帮助,如果不是,那么你可能会使用LINQ(调用WhereSingle)。

fv2wmkja

fv2wmkja2#

使用linq:

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

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

编辑:

因为stuff是一个结构体,所以SingleOrDefault()不会返回null,但是它会返回 default(stuffs),它的ID为0。当你的 normal stuff-objects的ID不是0时,你可以查询这个ID:

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

yfwxisqw3#

如果您有LINQ:

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

quhf5bfb4#

prods.Remove(prods.Find(x => x.ID == 1));
0sgqnhkj

0sgqnhkj5#

以下是一个解决方案,适用于那些希望使用实体框架将其从数据库中删除的用户:
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);
        }
    }
}

P.S.这模拟了RemoveAll()方法,该方法不适用于实体框架的DB集。

gajydyqb

gajydyqb6#

prods.Remove(prods.Single(p=>p.ID == 1));
你不能在foreach中修改collection,就像Vincent建议的那样

ubby3x7f

ubby3x7f7#

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

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;
    }
}
2lpgd968

2lpgd9688#

然而,现在已经晚了一点,一个简单的扩展方法可以在IList<T>上实现RemoveAll。诀窍是以相反的顺序循环集合,以避免删除当前项以及在删除时必须尝试当前索引的额外逻辑。相反的顺序还可以避免复制所有剩余项。根据.NET版本的不同,这种复制可能会很昂贵。

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

ddarikpa9#

你可以用林肯。

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

相关问题