如何使用IEqualityComparer,LinQ Distinct从集合中删除重复项

Gun*_*Gun 33 c# linq list

我无法从集合中删除重复项,我已经为类Employee实现了IEqualityComparer仍然没有得到输出

static void Main(string[] args)
    {
        List<Employe> Employeecollection = new List<Employe>();

        Employeecollection.Add(new Employe("abc","def"));
        Employeecollection.Add(new Employe("lmn","def"));
        Employeecollection.Add(new Employe("abc", "def"));

        IEnumerable<Employe> coll = Employeecollection.Distinct(new Employe());

        foreach (Employe item in coll)
        {
            Console.WriteLine(item.fName + "   " + item.lName );
        }

    }
Run Code Online (Sandbox Code Playgroud)

下面是Employee类实现,这里我实现了IEqualityComparer

class Employe : IEqualityComparer<Employe>
{
    public string fName { get; set; }
    public string lName { get; set; }

    public Employe()
    {

    }

    public Employe(string firstName, string LastName)
    {
        this.fName = firstName;
        this.lName = LastName;
    }

    #region IEqualityComparer<pcf> Members

    public bool Equals(Employe x, Employe y)
    {
        if (x.fName == y.fName && x.lName == y.lName)
        {
            return true;
        }

        return false;
    }

    public int GetHashCode(Employe obj)
    {
        return obj.GetHashCode();
    }

    #endregion
}
Run Code Online (Sandbox Code Playgroud)

spe*_*der 95

忘记IEqualityComparer并直接使用Linq:

EmployeeCollection.GroupBy(x => new{x.fName, x.lName}).Select(g => g.First());
Run Code Online (Sandbox Code Playgroud)

  • GroupBy操作将返回IEnumerable的[IGrouping](http://msdn.microsoft.com/en-us/library/bb344977.aspx)项目(也是IEnumerables).在你的例子中,外部IEnumerable中将有两个项目:一个IGrouping,每个"abc","def"有两个条目; 另一个IGrouping,其中一个条目为"lmn","def".First()运算符将从内部IGrouping IEnumerables中取出第一个项目. (6认同)

Ily*_*nov 5

您需要覆盖GetHashCode员工中的方法。你没有这样做。下面给出了一个好的散列方法的例子:(由ReSharper生成)

public override int GetHashCode()
{
    return ((this.fName != null ? this.fName.GetHashCode() : 0) * 397) ^ (this.lName != null ? this.lName.GetHashCode() : 0);
}
Run Code Online (Sandbox Code Playgroud)

现在Distinct调用后,foreach 循环打印:

abc   def
lmn   def
Run Code Online (Sandbox Code Playgroud)

在您的情况下,您正在调用 object 的 class GetHashCode,它对内部字段一无所知。

一个简单的说明,MoreLINQ包含DistinctBy扩展方法,它允许您执行以下操作:

IEnumerable<Employe> coll = 
 Employeecollection.DistinctBy(employee => new {employee.fName, employee.lName});
Run Code Online (Sandbox Code Playgroud)

匿名对象对GetHashCodeEquals方法都有正确的实现。


Nik*_*tev 5

这是一个很好的教程

    public int GetHashCode(Employe obj)
    {
        return obj.fname.GetHashCode() ^ obj.lname.GetHashCode();
    }
Run Code Online (Sandbox Code Playgroud)

  • 如果不实现相等的成员,就不应该实现GetHashCode.GetHashCode也应该是一个覆盖.另外值得记住的是,当数据结构存在冗余时,*"'xor'可能会造成或加剧分发问题."*:http://blogs.msdn.com/b/ericlippert/archive/2011/02/28/guidelines-和规则换gethashcode.aspx (4认同)