从列表1中删除不在列表2中的项目

时间:2010-11-01 01:33:32

标签: c# lambda

我正在学习编写lambda expressions,我需要有关如何从列表中删除不在另一个列表中的所有元素的帮助。

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

4 个答案:

答案 0 :(得分:60)

您可以使用Contains:

通过RemoveAll执行此操作
list.RemoveAll( item => !list2.Contains(item));

或者,如果您只想要交叉点,使用Enumerable.Intersect会更有效:

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

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

答案 1 :(得分:10)

对象解决方案(可能比horaces解决方案更容易):

如果您的列表包含对象而不是标量,那么通过删除对象的一个​​选定属性就可以了:

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

答案 2 :(得分:9)

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

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

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

这是我的解决方案:

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

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

        return false;
    }
}

在我这样做之后,Reed Copsey的上述RemoveAll()答案对我来说非常适合。

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

答案 3 :(得分:9)

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