使用自定义的IEqualityComparer使用LINQ相交 [英] Intersect with a custom IEqualityComparer using Linq

查看:185
本文介绍了使用自定义的IEqualityComparer使用LINQ相交的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

长话短说:我有对象的2集合。其中包括良好的价值观(让我们称之为好),其他默认值(先生默认)。我想联盟的相交好和默认和默认之间。换句话说:相交(联盟(好,默认值),默认值)。有人可能会认为它解析为默认设置,但这里是它得到棘手。我使用自定义的IEqualityComparer

Long story short: I have 2 collections of objects. One contains good values (Let's call it "Good"), the other default values (Mr. "Default"). I want the Intersect of the Union between Good and Default, and Default. In other words: Intersect(Union(Good, Default), Default). One might think it resolves as Default, but here is where it gets tricky : I use a custom IEqualityComparer.

我得到了以下的类:

class MyClass
{
    public string MyString1;
    public string MyString2;
    public string MyString3;
}

class MyEqualityComparer : IEqualityComparer<MyClass>
{
    public bool Equals(MyClass item1, MyClass item2)
    {
        if(item1 == null && item2 == null)
            return true;
        else if((item1 != null && item2 == null) ||
                (item1 == null && item2 != null))
            return false;

        return item1.MyString1.Equals(item2.MyString1) &&
               item1.MyString2.Equals(item2.MyString2);
    }

    public int GetHashCode(MyClass item)
    {
        return new { item.MyString1, item.MyString2 }.GetHashCode();
    }
}

下面是我收集好,并默认集合的特征

Here are the characteristic of my collections Good and Default collections :

默认:这是一个大组,包含所有想要{MyString1,MyString2}对,但MyString3值,你可以猜到,默认值

Default : It's a large set, containing all the wanted { MyString1, MyString2 } pairs, but the MyString3 values are, as you can guess, default values.

好:这是一个小集,主要包含这是在默认设置的项目,但也有一些很好的MyString3值。它也有一些{MyString1,MyString2}是想要的设置之外

Good : It's a smaller set, containing mostly items which are in the Default set, but with some good MyString3 values. It also has some { MyString1, MyString2 } that are outside of the wanted set.

我想要做的是:仅是在默认的从优秀项目,但在默认情况下添加其他项目到

What I want to do is this : Take only the items from Good that are in Default, but add the other items in Default to that.

在这里,我的想法是,我最好的尝试:

Here is, what I think is, my best try :

HalfWantedResult = Good.Union(Default, new MyEqualityComparer());
WantedResult= HalfWantedResult.Intersect(Good, new MyEqualityComparer());



我教它应该有工作,但结果我得到的是基本上只有好{MyString1,MyString2 }对设定,但是所有从默认设置来了,所以我全部横跨具有默认值。我也试过切换默认和最后相交的好,但我得到了相同的结果。

I taught it should have worked, but the result I get is basically only the good { MyString1, MyString2 } pairs set, but all coming from the Default set, so I have the default value all across. I also tried switching the Default and Good of the last Intersect, but I get the same result.

推荐答案

这一切首先是错误:

public bool Equals(MyClass item1, MyClass item2)
{
    return GetHashCode(item1) == GetHashCode(item2);
}

如果的哈希码的是肯定的相应的2项是不同的,但如果不同它们相等不能保证相应的2项是相等的。

If the hashcode's are different for sure the corresponding 2 items are different, but if they're equal is not guaranteed that the corresponding 2 items are equal.

因此,这是正确的等于实施

public bool Equals(MyClass item1, MyClass item2)
{
    if(object.ReferenceEquals(item1, item2))
        return true;
    if(item1 == null || item2 == null)
        return false;
    return item1.MyString1.Equals(item2.MyString1) &&
           item1.MyString2.Equals(item2.MyString2);
}



作为的西裤建议(期待我)的代码如下:

As Slacks suggested (anticipating me) the code is the following:

var Default = new List<MyClass>
{
    new MyClass{MyString1="A",MyString2="A",MyString3="-"},
    new MyClass{MyString1="B",MyString2="B",MyString3="-"},
    new MyClass{MyString1="X",MyString2="X",MyString3="-"},
    new MyClass{MyString1="Y",MyString2="Y",MyString3="-"},
    new MyClass{MyString1="Z",MyString2="Z",MyString3="-"},

};
var Good = new List<MyClass>
{
    new MyClass{MyString1="A",MyString2="A",MyString3="+"},
    new MyClass{MyString1="B",MyString2="B",MyString3="+"},
    new MyClass{MyString1="C",MyString2="C",MyString3="+"},
    new MyClass{MyString1="D",MyString2="D",MyString3="+"},
    new MyClass{MyString1="E",MyString2="E",MyString3="+"},
};
var wantedResult = Good.Intersect(Default, new MyEqualityComparer())
                       .Union(Default, new MyEqualityComparer());

// wantedResult:
// A A +
// B B +
// X X -
// Y Y -
// Z Z -

这篇关于使用自定义的IEqualityComparer使用LINQ相交的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆