2013-05-17 106 views
8

如何使用LINQ从基于另一个IList的IList中删除某些元素。 我需要从列表1中删除记录,其中ID在列表2中存在。 下面是代码示例,LINQ从IList中删除某些元素<T>基于IList <int>

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

这是我正在做呢,有没有更好的方式来这样做。

+6

没有一天没有类似的问题。 –

+0

不要为此使用Linq。 Linq全部是关于过滤和创建新序列,而不是修改集合。 –

回答

8

可以使用Where更简单:

list1 = list1.Where(x => !list2.Contains(x.ID)) 
      .ToList(); 

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

+3

RemoveAll不返回一个列表,它返回一个int值,它表示删除的项目数。 –

+0

@RobertJ .:编辑我的回答 –

+0

@RobertJ。你应该使用RemoveAll,看我的回答 –

12

我会用这种方法:

var itemsToRemove = list1.Where(x => list2.Contains(x.ID)).ToList(); 
foreach(var itemToRemove in itemsToRemove) 
    list1.Remove(itemToRemove); 

这种方法删除这些项目。最适用于list1中有很多项目和list2中很少项目的情况。
如果list1list2中的物品数量是相似的,Cuong Le的方法是一个很好的选择。

+1

为什么'Where'后面的'ToList()'?不要认为这是必要的。 –

+2

@GeorgeDuckett:是的,这是必要的。否则'itemsToRemove'遍历'list1'。与'Remove'一起,这将产生一个'InvalidOperationException':*集合已被修改;枚举操作可能不会执行* –

+0

啊,好点,忘了这一点。 –

11

您可以为IList<T>编写一个“RemoveAll()”扩展方法,其工作方式与List.RemoveAll()完全相同。 (这通常是足够有用的,以保持在一个共同的类库。)

例如(为清楚起见检查删除错误,你需要检查参数不为null):

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

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

list1.RemoveAll(item => list2.Contains(item.ID)); 
相关问题