2011-03-10 144 views
1

我有以下实现来查找DataTable中的重复项。这是非常低效的,并且需要大约20K行。我只需要找到重复项,第二列的值:删除数据表中的重复项

private List<string> checkForDuplicates(DataTable results) 
{ 
    List<string> duplicateLists = new List<string>(); 
    for (int i = 0; i < results.Rows.Count; i++) 
    { 
     string cellvalue = results.Rows[i][1].ToString(); 
     for (int j = 0; j < results.Rows.Count; j++) 
     { 
      if (i != j) 
      { 
      if (cellvalue.Equals(results.Rows[j][1])) 
       { 
        //Duplicate found        
        duplicateLists.Add(results.Rows[i][1].ToString() + "_" + i+2 + "_" + j+2); 
       } 
      } 
     } 

    } 
    return duplicateLists; 
} 
+1

你有比较的专栏索引吗? – NikoRoberts 2011-03-10 14:53:37

回答

1

你得到的问题是,每一行都必须检查每隔一行,因此对于更多的行,检查的次数呈指数增长。处理它的最快方法是使它成为线性的 - 只做多行检查。

执行此操作的一种方法是按列2对数据表进行排序。这会将任何重复项放在相邻的行中,因此您只需要遍历表来检查一行是否与下一行不匹配。

另一种方式是从源头获取东西,并在读取它们之前确保行是不同的。

+0

Aaargh,为什么我没有想到,今天脑死亡。谢谢。 – n4rzul 2011-03-10 14:58:23

+0

但排序也意味着对比值彼此,不? – Matthias 2011-03-10 15:02:20

+0

@bender。当发生这种情况时,发生这种情况:假设你有3行,那么检查的次数是3 * 3 = 9(粗略地说,其中的一些可能会被省略,但其大致为真)。当您添加另一行时,您有4 * 4 = 16个检查,然后是25,36等。因此对于20K行,您有4亿检查。当你排序时,你只需要检查下一行,因此对于3行你需要2次检查。对于4行,您需要3.对于20k行,您需要19,999个检查。这就是为什么你在性能上有了这样的改进。 – 2011-03-10 15:35:33

0

来源:http://social.msdn.microsoft.com/Forums/en/adodotnetdataset/thread/ed9c6a6a-a93e-4bf5-a892-d8471b84aa3b

DataTable distinctTable = originalTable.DefaultView.ToTable(/*distinct*/ true);

你的目的,你可以做一个数据视图仅包含列()你”重新感兴趣。

+0

难道不是所有的列都不能区分而不是仅仅是列吗? – 2011-03-10 14:54:47

+0

就像我说过的,你可以创建一个DataView,其中只包含column2,或者显然你可以使用列表调用ToTable:DataTable uniqueTable = dvwDataView.ToTable(true,“name”,“next_column_name”,“another_column_name”); – 2011-03-10 14:57:04

+0

它会,不是什么即时通讯寻找,乔恩你的第一个答案是完美的。 – n4rzul 2011-03-10 14:58:01

1

您可以做的一个优化是对已排序的数据集进行重复数据删除。定义一个DataView,对相关列的数据进行排序,然后检查当前行的值是否与前一行的值不同。

马克索索尔的答案可能是一个更好的主意,如果你不打扰物理删除行然而。

0

SQL会更有效地完成此操作,而不是将整个数据集拉两次。

如果您所指的列上有索引,则可以非常快速地完成。

只是做

SELECT id AS matchID, column1 FROM table1 WHERE column1 IN (SELECT column1 FROM table1 WHERE id IS NOT matchId) 

或类似的东西

干杯, 尼科

+0

源数据是csv – n4rzul 2011-03-15 05:59:39

1

使用字典和全值迭代一次,并计算每个值的发生=>词典关键是列值,字典值是计数。 然后返回计数超过一个的所有键。

+0

这个工作得很好,但我去了Jon的回答是,因为他的解决方案让我感觉更自然。结果代码很容易理解,我正在处理大约20-60K行。 60K行觉得它永远不会完成旧的“比较所有值”方法,其中排序和检查相邻记录几乎是即时的,包括排序。 – n4rzul 2011-03-15 06:03:54