Linq 检查列表中的每个对象是否存在于另一个列表中

Linq 检查列表中的每个对象是否存在于另一个列表中,linq,c#-4.0,Linq,C# 4.0,我有两个同一类的列表: class Test { int A; String B; Char C; } Element of two lists are: List<Test> obj1 : 1 “Abc” 'a' 2 “Bcd” 'b' List<Test> obj2: 1 “Abc” 'a' 2 “Bcd” 'b' 3 “Cde” 'c' 4 “Def” 'd' 5 “Efg” 'e' 我想检查obj

我有两个同一类的列表:

class Test
{
int A;
String B;
Char C;
}

Element of two lists are:

List<Test> obj1 :

1   “Abc”   'a'
2   “Bcd”   'b'

List<Test> obj2:

1   “Abc”   'a'
2   “Bcd”   'b'
3   “Cde”   'c'
4   “Def”   'd'
5   “Efg”   'e'

我想检查obj2中是否存在obj1行。例如,obj1的前两行在obj2中。我使用循环实现了这一点。任何人都可以通过linq查询或不使用循环来帮助我做同样的事情。任何帮助都将不胜感激。

如果您的列表共享相同的对象实例,您可以查看@lazyberezovsky关于覆盖Equals和GetHashCode方法的帖子,您可以使用LINQ Any。如果obj1中的项目位于obj2中,则返回true:

编辑

如果我误解了一些评论员的建议,您想检查obj1中的所有对象是否都存在于obj2中,那么可以使用LINQ all。如果obj1中的所有项目都存在于obj2中,则返回true:


如果您的列表共享相同的对象实例,您可以看到@lazyberezovsky关于覆盖Equals和GetHashCode方法的帖子,您可以使用LINQ Any。如果obj1中的项目位于obj2中,则返回true:

编辑

如果我误解了一些评论员的建议,您想检查obj1中的所有对象是否都存在于obj2中,那么可以使用LINQ all。如果obj1中的所有项目都存在于obj2中,则返回true:


如果不想覆盖Equals和GetHashCode,或为对象创建自定义比较器,则可以将这两个列表投影到匿名对象中:

obj1.Select(t => new { t.A, t.B, t.C })
    .Except(obj2.Select(t => new { t.A, t.B, t.C })
    .Any();
如果您的列表共享相同的对象实例,那么它将通过引用比较对象

obj1.Except(obj2).Any()
如果要将Equals和GetHashCode实现添加到类中,可以使用这种方法。请参见下面的实现示例。还可以为测试类创建比较器:

public class TestComparer : IEqualityComparer<Test>
{
    public bool Equals(Test x, Test y)
    {
        return (x.A == y.A) && (x.B == y.B) && (x.C == y.C);
    }

    public int GetHashCode(Test obj)
    {
        int hash = 19;
        hash = hash * 17 + obj.A.GetHashCode();
        hash = hash * 17 + obj.B.GetHashCode();
        hash = hash * 17 + obj.C.GetHashCode();
        return hash;
    }
}

如果不想覆盖Equals和GetHashCode,或为对象创建自定义比较器,则可以将这两个列表投影到匿名对象中:

obj1.Select(t => new { t.A, t.B, t.C })
    .Except(obj2.Select(t => new { t.A, t.B, t.C })
    .Any();
如果您的列表共享相同的对象实例,那么它将通过引用比较对象

obj1.Except(obj2).Any()
如果要将Equals和GetHashCode实现添加到类中,可以使用这种方法。请参见下面的实现示例。还可以为测试类创建比较器:

public class TestComparer : IEqualityComparer<Test>
{
    public bool Equals(Test x, Test y)
    {
        return (x.A == y.A) && (x.B == y.B) && (x.C == y.C);
    }

    public int GetHashCode(Test obj)
    {
        int hash = 19;
        hash = hash * 17 + obj.A.GetHashCode();
        hash = hash * 17 + obj.B.GetHashCode();
        hash = hash * 17 + obj.C.GetHashCode();
        return hash;
    }
}

不应该是全部吗?@jdv jandavan不,这要求obj1中的所有元素都在obj2中。他只是想知道他们中是否有人。@gleng我认为jdv是对的,问题是:我想检查obj2中是否存在obj1行。@Wasafa1我不同意。obj2中obj1的任意行=任意。obj1中的所有行都显示在obj2=All中。@gleng:非常感谢gleng。难道不是全部吗?@jdv Jandavan不,这要求obj1中的所有元素都在obj2中。他只是想知道他们中是否有人。@gleng我认为jdv是对的,问题是:我想检查obj2中是否存在obj1行。@Wasafa1我不同意。obj2中obj1的任意行=任意。obj1中的所有行都出现在obj2=All中。@gleng:非常感谢gleng。使用Join可能会更快,例如obj1.Joinobj2,t=>new{t.a,t.B,t.C},t=>new{t.a,t.B,t.C},t1,t2=>true.Any;而不是Except。@DominicKexel对此不确定-JoinIterator为内部序列创建查找,然后在外部序列上迭代。Exceptionator也这样做,但使用SetIt可能会更快地使用Join,例如obj1.Joinobj2,t=>new{t.A,t.B,t.C},t=>new{t.A,t.B,t.C},t1,t2=>true.Any;而不是Except。@DominicKexel对此不确定-JoinIterator为内部序列创建查找,然后在外部序列上迭代。Exceptionator也执行相同的操作,但使用Set