2011-03-10 142 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