从对象数组中删除重复项

时间:2015-12-07 20:22:00

标签: c# arrays class duplicates

我有一个名为Customer的类,它有几个字符串属性,如

firstName, lastName, email, etc.  

我从csv文件中读取了客户信息,该文件创建了一个类的数组:

Customer[] customers  

我需要删除具有相同电子邮件地址的重复客户,每个特定电子邮件地址只留下1条客户记录。

我使用2个循环完成了这项工作,但由于通常有50,000多个客户记录,因此需要将近5分钟。完成删除重复项后,我需要将客户信息写入另一个csv文件(此处无需帮助)。

如果我在循环中执行了Distinct,我该如何删除属于该特定客户的类的其他字符串变量?

谢谢, 安德鲁

2 个答案:

答案 0 :(得分:6)

使用Linq,您可以在O(n)时间(单级循环)中使用GroupBy

执行此操作
var uniquePersons = persons.GroupBy(p => p.Email)
                           .Select(grp => grp.First())
                           .ToArray();

<强>更新

O(n)的{​​{1}}行为。

GroupBy已在GroupByLinq)中实施,因此 -

Enumerable.cs仅迭代一次以创建分组。所提供密钥的IEnumerable(例如&#34;电子邮件&#34;此处)用于查找唯一密钥,并且元素将添加到与密钥对应的Hash中。

请参阅此GetGrouping代码。还有一些旧帖子供参考。

然后Grouping显然是一个O(n)代码,整体上面代码为Select

更新2

处理O(n) / empty值。

因此,如果有null的值为Emailnull的情况,则简单的empty只会从GroupBy中获取其中一个对象}&amp;每个null

包含empty / null值的所有对象的一种快捷方法是在运行时为这些对象使用一些唯一键,例如

empty

答案 1 :(得分:0)

我会这样做:

public class Person {
    public Person(string eMail, string Name) {
        this.eMail = eMail;
        this.Name = Name;
    }
    public string eMail { get; set; }
    public string Name { get; set; }
}
public class eMailKeyedCollection : System.Collections.ObjectModel.KeyedCollection<string, Person> {
    protected override string GetKeyForItem(Person item) {
        return item.eMail;
    }
}

public void testIt() {
    var testArr = new Person[5];
    testArr[0] = new Person("Jon@Mullen.com", "Jon Mullen");
    testArr[1] = new Person("Jane@Cullen.com", "Jane Cullen");
    testArr[2] = new Person("Jon@Cullen.com", "Jon Cullen");
    testArr[3] = new Person("John@Mullen.com", "John Mullen");
    testArr[4] = new Person("Jon@Mullen.com", "Test Other"); //same eMail as index 0...

    var targetList = new eMailKeyedCollection();
    foreach (var p in testArr) {
        if (!targetList.Contains(p.eMail))
            targetList.Add(p);
    }
}

如果在集合中找到该项目,您可以使用以下方法轻松选择(并最终修改)

        if (!targetList.Contains(p.eMail))
            targetList.Add(p);
        else {
           var currentPerson=targetList[p.eMail];
           //modify Name, Address whatever... 
        }