从包含具有数组元素的类的列表中删除重复项

时间:2012-09-17 14:49:08

标签: c# list duplicate-removal

我有一个包含类中对象的列表。包含各种项目的类,包括int和double数组。这堂课看起来像这样。

public class NewChildren
{
    public double[] fitnessValue{get;set;}

    public int[] locationScheme{get;set;}

    public double crowdingDistance{get;set;}
}

由于列表可能包含重复项,我有兴趣删除它们。在网络上,我看到了一些基于Linq的解决方案,它们使用了Distinct()和GroupBy()方法。但是,似乎这些方法不起作用,因为对象中有数组(MSVS2008不会给出任何错误,但也没有删除项目。)

我们非常感谢任何建议(包括参考或代码)。提前谢谢。

3 个答案:

答案 0 :(得分:1)

docs中所述,Distinct默认使用默认的相等比较器。该默认的相等比较器将列表中的每个项目识别为与其他项目不同,因为它会检查实例标识。

如前面提到的文档中所述,为了比较自定义类型并定义您想要的相等性,您需要在类上实现一些与比较相关的方法:

  

要比较自定义数据类型,您需要实施[IEquatable<T>]并为该类型提供自己的GetHashCodeEquals方法。

答案 1 :(得分:1)

NewChildren的两个实例相同时,您必须问自己的问题是什么?既然你有列表,这可能不是一个容易回答的问题。定义后,必须在类中实现相等方法:

public class NewChildren
{
    public double[] fitnessValue{get;set;}

    public int[] locationScheme{get;set;}

    public double crowdingDistance{get;set;}

    public bool override Equals(object other)
    {
        // ... implement your rules for equality here
    }
}

现在,为此,您必须始终关注Microsoft guidelines。覆盖相等不是 简单,尽管它并不复杂。例如,您将拥有具有相同元素的所有数组:

public bool override Equals(object other)
{
    if (other == null || !(other is NewChildren)) 
    {
        return false;
    }

    var another = (NewChildren)other;

    return AreEquivalent(this.fitnessValue, another.fitnessValue)
        && AreEquivalent(this.locationScheme, another.locationScheme)
        && AreEquivalent(this.crowdingDistance, another.crowdingDistance);

}

public static bool AreEquivalent<T>(T[] a, T[] b)
{
    return a1.OrderBy(a => a).SequenceEqual(a2.OrderBy(a => a));
}

数组相等的实现取自here。您可以使用this reference优化它。

答案 2 :(得分:0)

默认情况下,通过检查引用相等性来评估从类创建的对象的Equals方法和等于运算符。这意味着只有在引用同一个类实例时,两个项才相等。您需要更改查询以检查类中的各个属性,或者实现适当方法和运算符的覆盖。

请参阅MSDN上的以下内容: