删除自定义IComparable类中的重复项

本文关键字:自定义 IComparable 删除 | 更新日期: 2023-09-27 18:03:40

我有一个包含组合对标识符的表,我使用它来遍历CSV文件查找匹配。我将未识别的对捕获在List中,并将它们发送到输出框,以便稍后添加。我希望输出只出现一次唯一对。类的声明如下:

    public class Unmatched:IComparable<Unmatched>
{
    public string first_code { get; set; }
    public string second_code { get; set; }
    public int CompareTo(Unmatched other)
    {
        if (this.first_code == other.first_code)
        {
            return this.second_code.CompareTo(other.second_code);
        }
        return other.first_code.CompareTo(this.first_code);
    }
 }

上面的代码需要注意的一点是:这将以相反的字母顺序返回它,使用这一行来获得它的字母顺序:

return this.first_code.CompareTo(other.first_code);
下面是添加它的代码。这是直接在对数据表元素 进行比较之后。
unmatched.Add(new Unmatched() 
{ first_code = fields[clients[global_index].first_match_column]
, second_code = fields[clients[global_index].second_match_column] });

我想从列表中删除所有第一码和第二码相等的对,即;

PTC,138A
PTC,138A
PTC,138A
MA9,5A
MA9,5A
MA9,5A
MA63,138A
MA63,138A
MA59,87BM
MA59,87BM

应该成为:

PTC, 138A
MA9, 5A
MA63, 138A
MA59, 87BM

我已经尝试添加我自己的等号和GetHashCode概述如下:http://www.morgantechspace.com/2014/01/Use-of-Distinct-with-Custom-Class-objects-in-C-Sharp.html

我尝试过的SE链接在这里:

如何区分键/值对列表

获取list 在c#中

获取list

中不同值的列表

它们都返回一个仍然包含所有对的列表。下面是输出列表的当前代码(是的,我知道有两个不同的行,似乎都不工作):

    parser.Close();
    List<Unmatched> noDupes = unmatched.Distinct().ToList();
    noDupes.Sort();
    noDupes.Select(x => x.first_code).Distinct();
    foreach (var pair in noDupes)
    {
        txtUnmatchedList.AppendText(pair.first_code + "," + pair.second_code + Environment.NewLine);
    }

这是请求的equequity/Hash码:

public bool Equals(Unmatched notmatched)
{
    //Check whether the compared object is null.  
    if (Object.ReferenceEquals(notmatched, null)) return false;
    //Check whether the compared object references the same data.  
    if (Object.ReferenceEquals(this, notmatched)) return true;
    //Check whether the UserDetails' properties are equal.  
    return first_code.Equals(notmatched.first_code) && second_code.Equals(notmatched.second_code);
}
// If Equals() returns true for a pair of objects   
// then GetHashCode() must return the same value for these objects.  
public override int GetHashCode()
{
    //Get hash code for the UserName field if it is not null.  
    int hashfirst_code = first_code == null ? 0 : first_code.GetHashCode();
    //Get hash code for the City field.  
    int hashsecond_code = second_code.GetHashCode();
    //Calculate the hash code for the GPOPolicy.  
    return hashfirst_code ^ hashsecond_code;
}

我还看了几个使用查询和元组的答案,我真的不理解。谁能给我指出一个来源或答案来解释如何(以及为什么)从自定义列表中获得不同的配对?

(附带问题-可以将一个类声明为既可比较又可等价的吗?)

删除自定义IComparable类中的重复项

问题是你没有实现IEquatable<Unmatched>

public class Unmatched : IComparable<Unmatched>, IEquatable<Unmatched>

EqualityComparer<T>.Default仅在实现IEquatable<T>时使用Equals(T)方法。你没有这样做,所以它将使用Object.Equals(object),它使用引用相等。

您正在调用的Distinct的重载使用EqualityComparer<T>.Default来比较序列的不同元素是否相等。正如文档所述,返回的比较器使用GetHashCode的实现来查找可能相等的元素。然后使用Equals(T)方法检查是否相等,如果没有实现IEquatable<T>,则使用Object.Equals(Object)

你有一个Equals(Unmatched)方法,但它不会被使用,因为你没有实现IEquatable<Unmatched>。相反,使用默认的Object.Equals方法,它使用引用相等性。

请注意,当前的Equals方法不会覆盖Object.Equals,因为它接受Object参数,并且您需要指定override修饰符。

使用Distinct的例子见这里。

你必须实现IEqualityComparer<TSource>而不是IComparable<TSource>