如何从列表中消除重复项

本文关键字:列表 | 更新日期: 2023-09-27 18:10:41

class infoContact
{ 

    private string contacts_first_nameField;
    private string contacts_middle_nameField;
    private string contacts_last_nameField;        
    private Phonenumber[] phone_numbersField;
    private Emailaddress[] emailField;
}

我有一个List<infoContact>列表包含近7000我从一些其他程序。在7000个名单中,有6500个是重复的。我正在寻找一种方法,如何消除重复。

如果first_name、last_name、emailaddresses、phone number相同,则infoContact为重复。

我想使用HashSet<infoContact>并覆盖infoContact的getHashCode()。

我只是想知道这是否是最好的方法。如果这不是一个好方法,什么是更好的方法?

如何从列表中消除重复项

可以使用以IEqualityComparer<T>为参数的Distinct扩展方法。只要写一个类来实现那个接口,并进行比较,然后你就可以这样做:

var filteredList = oldList.Distinct(new InfoContactComparer());

用你想要的参数覆盖一个equals方法,这样你就可以通过equals来比较对象

我创建了一个remove deleted items from list class,这里是它的键,

List<string> list = new List<string>();
        foreach (string line in File.ReadAllLines(somefile.txt))
        {
            if (!list.Contains(line))
            {
                list.Add(line);
            }
        }

首先考虑提取唯一值。您可以将Distinct() Linq方法与以下比较器一起使用:

public class infoContactComparer : IEqualityComparer<infoContact>
{
    public bool Equals(infoContact x, infoContact y)
    {
        return x.contacts_first_nameField == y.contacts_first_nameField
            && x.contacts_last_nameField == y.contacts_last_nameField
            && ...
    }
    public int GetHashCode(infoContact obj)
    {
        return obj.contacts_first_nameField.GetHashCode();
    }
}

两个选项:覆盖GetHashCodeEquals如果你控制infoContact的来源你的覆盖将为真任何特定的使用类

否则,定义一个实现IEqualityComparer<infoContact>的类,它还允许您定义适当的EqualsGetHashCode方法,然后将其实例传递给HashSet<infoContact>构造函数listOfContacts.Distinct方法调用(使用Linq)。

注意:你的问题似乎是基于GetHashCode应该决定平等或唯一性的想法。它不应该!它是工具的一部分,它允许HashSet完成它的工作,但不要求它为不相等的实例返回唯一值。这些值应该很好地分布,但它们最终可能重叠。

简而言之,两个相等的实例应该具有相同的哈希码,但共享相同哈希码的两个实例不一定相等。有关GetHashCode指南的更多信息,请访问此博客

正确的方法是重写equals方法!

这样,当你在列表中添加新元素时,该元素不会被添加!

实现infoContact类作为IEquatable<infoContact>的派生类:

class InfoContact : IEquatable<InfoContact> {
  string contacts_first_nameField;
  string contacts_last_nameField;
  object[] phone_numbersField;
  object[] emailField;
  // other fields
  public bool Equals(InfoContact other) {
    return contacts_first_nameField.Equals(other.contacts_first_nameField)
           && contacts_last_nameField.Equals(other.contacts_last_nameField)
           && phone_numbersField.Equals(other.phone_numbersField)
           && emailField.Equals(other.emailField);
  }
}

并使用Linqs的Enumerable.Distinct方法来过滤重复项:

var infoContacts = GetInfoContacts().Distinct();