LINQ基于IList <int>从IList <T>中删除某些元素

pas*_*per 8 c# linq ilist

如何使用LINQ从IList中删除基于另一个IList的某些元素.我需要从list1中删除记录,其中ID存在于list2中.下面是代码示例,

class DTO
{

    Prop int ID,
    Prop string Name
}

IList<DTO> list1;

IList<int> list2;



foreach(var i in list2)
{
    var matchingRecord = list1.Where(x.ID == i).First();
    list1.Remove(matchingRecord);
}
Run Code Online (Sandbox Code Playgroud)

我就是这样做的,有没有更好的方法来做同样的事情.

Mat*_*son 14

您可以编写一个"RemoveAll()"扩展方法,IList<T>其工作方式与此类似List.RemoveAll().(这通常足以保存在公共类库中.)

例如(为清楚起见,删除了错误检查;您需要检查参数是否为空):

public static class IListExt
{
    public static int RemoveAll<T>(this IList<T> list, Predicate<T> match)
    {
        int count = 0;

        for (int i = list.Count - 1; i >= 0; i--)
        {
            if (match(list[i]))
            {
                ++count;
                list.RemoveAt(i);
            }
        }

        return count;
    }        
Run Code Online (Sandbox Code Playgroud)

然后根据需要从list1中删除项目确实会变得如此简单:

list1.RemoveAll(item => list2.Contains(item.ID));
Run Code Online (Sandbox Code Playgroud)


Dan*_*rth 12

我会用这种方法:

var itemsToRemove = list1.Where(x => list2.Contains(x.ID)).ToList();
foreach(var itemToRemove in itemsToRemove)
    list1.Remove(itemToRemove);
Run Code Online (Sandbox Code Playgroud)

此方法删除了适当的项目.它最适用于有很多物品list1和很少物品的情况list2.
如果物品的数量list1list2类似,Cuong Le的方法是一个很好的选择.

  • @GeorgeDuckett:是的,这是必要的.否则`itemsToRemove`迭代`list1`.与`Remove`一起产生`InvalidOperationException`:*Collection被修改; 枚举操作可能无法执行* (2认同)

cuo*_*gle 8

您可以使用Where更简单:

list1 = list1.Where(x => !list2.Contains(x.ID))
             .ToList();
Run Code Online (Sandbox Code Playgroud)

但你真的需要删除,更喜欢@ DanielHilgarth的回答

  • RemoveAll不返回列表,它返回一个int,表示删除的项目数. (3认同)