2010-11-01 196 views
25

我正在学习编写lambda expressions,我需要帮助了解如何从列表中删除不在另一个列表中的所有元素。通过removeall过从列表1中删除项目不在列表2中

var list = new List<int> {1, 2, 2, 4, 5}; 
var list2 = new List<int> { 4, 5 }; 

// Remove all list items not in List2 
// new List Should contain {4,5}  
// The lambda expression is the Predicate. 
list.RemoveAll(item => item. /*solution expression here*/); 

// Display results. 
foreach (int i in list) 
{ 
    Console.WriteLine(i); 
} 

回答

49

为此,您可以使用包含:

list.RemoveAll(item => !list2.Contains(item)); 

或者,如果你只是想交集,使用Enumerable.Intersect会更有效:

list = list.Intersect(list2).ToList(); 

不同的是,在后一种情况下,你不会得到重复的条目。例如,如果list2包含2,则在第一种情况下,您会得到{2,2,4,5},在第二种情况下,您将得到{2,4,5}

+0

如果您是比较对象而不是标量,请参阅我对此答案的增强(下面) – horace 2012-04-30 19:54:07

8

此问题已被标记为已回答,但有一个问题。如果你的列表包含一个对象,而不是一个标量,你需要做更多的工作。

我一遍又一遍地用Remove()和RemoveAt()以及各种各样的东西试过,没有一个能正常工作。我甚至无法使Contains()正常工作。从来没有匹配过任我被困住了,直到我怀疑它可能无法正确匹配项目。

当我意识到这一点时,我重构了类来实现IEquatable,然后它开始工作。

这里是我的解决方案:

class GenericLookupE : IEquatable<GenericLookupE> 
{ 
    public string ID { get; set; } 

    public bool  Equals(GenericLookupE other) 
    { 
     if (this.ID == other.ID)  return true; 

     return false; 
    } 
} 

我这样做后,里德·科普塞以上的removeAll()答案完全为我工作。

参见:http://msdn.microsoft.com/en-us/library/bhkz42b3.aspx

8
list = list.Except(list2).ToList(); 
2

比贺拉斯对象更简单的方法了:

如果您的列表中包含的对象,而不是一个标量,它是简单的,由一个选定的属性移除的对象:

var a = allActivePatientContracts.RemoveAll(x => !allPatients.Select(y => y.Id).Contains(x.PatientId));