使用LINQ </t>比较两个List <t>

时间:2011-07-16 13:29:30

标签: linq

我有两个Medecine对象列表:

List<Medecine> list1;
List<Medecine> list2;

MedecineIDMedecineName等属于Medecine的属性; “MedecineID是独一无二的。

我想要list1但不在list2;

中的列表对象

3 个答案:

答案 0 :(得分:3)

var query = list1.Except(list2);
var list1NotList2 = query.ToList();

这会为您提供list1但不是list2的所有项目。

请注意,您需要确保可以正确地比较Medecine个对象(通常是Equals / GetHashCode)。您还可以将自定义IEqualityComparer作为Except的最终参数传递。

有关Except的详细信息,请参阅here

答案 1 :(得分:2)

在LINQ中执行此操作的自然方法是使用Enumerable.Except方法:

var results = list1.Except(list2).ToList();

然而,为了实现这个目的,你必须在两个对象“相同”时告诉LINQ。您可以通过Medecine实现IEquatable<Medecine>来实现此目的:

class Medecine : IEquatable<Medecine>
{
    public int MedecineID { get; set; }
    public string MedecineName { get; set; }

    public override int GetHashCode() {
         return this.MedecineID;
    }

    public bool Equals(Medecine other)
    {
        if (ReferenceEquals(null, other)) {
            return false;
        }
        if (ReferenceEquals(this, other)) {
            return true;
        }
        return other.MedecineID == this.MedecineID;
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) {
            return false;
        }
        if (ReferenceEquals(this, obj)) {
            return true;
        }
        if (obj.GetType() != typeof(Medecine)) {
            return false;
        }
        return Equals((Medecine)obj);
    }
}

如果此方法不合适,您可以制作IEqualityComparer<Medecine>并将其作为附加参数传递给Except

class MyComparer : IEqualityComparer<Medecine>
{
    public bool Equals(Medecine x, Medecine y)
    {
        if (x == null && y == null) {
            return true;
        }

        if (x == null || y == null) {
            return false;
        }

        return x.MedecineID == y.MedecineID;
    }

    public int GetHashCode(Medecine obj)
    {
        return obj.MedecineID;
    }
}

var results = list1.Except(list2, new MyComparer()).ToList();

答案 2 :(得分:0)

如果你想避免为你的药类编写自定义比较对象,那么你可以将第二个列表中的“MedecineId”投影到一个新的集合中,然后使用IEnumerable.Contains()创建你的“所需”列表:

class Medecine
{
    public Guid MedecineId { get; set; }
    public String Name { get; set; }
    // whatever other fields
}

创建一些测试数据:

List<Guid> mIds = 
    new List<Guid>( Enumerable.Range( 0, 20 ).Select( n => Guid.NewGuid() ) );

List<Medecine> m1 = new List<Medecine>
(
    Enumerable.Range( 0, 10 ).Select( c => new Medecine() { MedecineId = mIds.ElementAt( c ), Name = c.ToString() } )
);

List<Medecine> m2 = new List<Medecine>
(
    Enumerable.Range( 5, 15 ).Select( d => new Medecine() { MedecineId = mIds.ElementAt( d ), Name = d.ToString() } )
);

然后得到你的结果很简单:

var excludedIds = m2.Select( m2s => m2s.MedecineId).Distinct();
var results = m1.Where( m1s => !excludedIds.Contains( m1s.MedecineId ));