亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何比較和更新包含大量項目的 2 個列表?

如何比較和更新包含大量項目的 2 個列表?

C#
小怪獸愛吃肉 2023-04-29 15:51:09
注意:使用 LINQ 連接解決了這個問題。我需要比較源列表中的列表值是否存在于目標列表中,如果是,則將其保存到第三個列表。我編寫的代碼確實有效,但它花費了很多時間,因為我的源列表有 30k 個項目,并且它將每個項目值與 1500 萬個目標列表進行比較,這需要很多時間。因為它每次都會遍歷整個列表(30k *1500 萬次)查看顯然不是最佳但可以完成工作的代碼。        // The below code will generate the lists from CSV file        The lists are below for sample        **Source List**        FileId  FilePath      FileChecksum        1       somepath A    check1        2       somepath AA   check2        3       somepath AAB  check3        4       somepath B    check4        5       somepath BB   check5        **Destination List**        StepId  StatusID  JobId ProjectId FileId     FilePath        5        6         4    2091      577206853  somepath A        5        6         4    2092      577206853  somepath AA        5        6         4    2093      577206853  somepath AAA        5        6         4    2094      577206853  somepath AB        5        6         4    2095      577206853  somepath A        5        6         4    2096      577206853  somepath B        5        6         4    2097      577206853  somepath BB        List<Source> SourceList = File.ReadAllLines(@"D:\source.csv").Skip(1).Select(v => Source.SourceFromCSv(v)).ToList();        List<Destination> DestinationList = File.ReadAllLines(@"D:\Destination.csv").Skip(1).Select(d => Destination.FromDestinationCSV(d)).ToList();        //This will compare and create a new list        var result1 =            from s in SourceList            from d in DestinationList            where (d.FilePath.ToLower() == s.FilePath.ToLower())             select (d.StepId + "," + d.StatusId + "," + d.JobId + "," +              d.ProjectId + "," + d.FileId + "," + d.FilePath + "," + 
查看完整描述

5 回答

?
皈依舞

TA貢獻1851條經驗 獲得超3個贊

您可以對兩個列表進行排序,然后逐行進行比較。算法復雜度為 O(n log n+n)。

您將第一行數據 A 與第一行數據 B 進行比較,然后在“較大”行上增加指針的索引。如果數據 A 有 8 而數據 B 有 7 和 9,當你達到 9 時,你就會知道數據 B 中不存在 8。

您應該開始比較最大可能的索引。這樣,如果列表確實是一個子列表,您可以快速終止。


查看完整回答
反對 回復 2023-04-29
?
慕尼黑8549860

TA貢獻1818條經驗 獲得超11個贊

你可以反過來做。您可以迭代 3000 萬個條目,而不是從 30k 個源條目中選擇一個。如果找到所有 30k 個條目,或者在最壞的情況下,找到 3000 萬個條目,則可以停止。那還是比 30K*15M 好。



查看完整回答
反對 回復 2023-04-29
?
拉丁的傳說

TA貢獻1789條經驗 獲得超8個贊

var query = from s in SourceList

 join d in DestinationList on 

 s.FilePath.ToLower().TrimEnd() equals d.FilePath.ToLower().TrimEnd()

 select (d.StepId + "," + d.StatusId + "," + d.JobId + "," +d.ProjectId + "," + d.FileId + "," + d.FilePath + "," + s.FileChecksum);

LINQ join 在不到 5 秒的時間內完成了同樣的事情。


查看完整回答
反對 回復 2023-04-29
?
蝴蝶刀刀

TA貢獻1801條經驗 獲得超8個贊

是的,如果您不需要列表的所有功能,將基本類型設置為 aHashSet<T>將顯著改善查找。您的自定義類型可能需要實現適當的GetHashCode()功能以進一步提高查找速度。

看:

  • HashSet<T>

  • GetHashCode()

不要調用new HashSet(query.ToList()),而是在實例化列表時直接轉換為哈希集,query.ToHashSet()可選地傳入一個 Equality Comparer,見下文:

  • ToHashSet(IEqualityComparer<T>)

除了自定義GetHashCode實現之外,您還可以實現自定義IEqualityComparer來處理特定情況,例如您的情況,其中特定字段構成了平等規則?,F在的 Visual Studio 和 Resharper 提供了一個內置的重構來生成GetHashCodeEquals.

看:

  • IEqualityComparer<T>

然后,您可以使用IntersectWith一次調用獲取兩組中的所有項目:

看:

  • IntersectWith()

創建一個可以將Source和轉換Destination為的特殊對象,或者為它們提供相同的基類將允許這樣做。

您也可以使用 aIDictionary<Key, Value>并使密鑰成為Item.FilePath.ToLower(),與上述相同的原則適用。這將允許運行時使用字符串檢查該項目是否存在于其他列表中GetHashCode,默認情況下這是高度優化的。


查看完整回答
反對 回復 2023-04-29
?
互換的青春

TA貢獻1797條經驗 獲得超6個贊

原則上,您所做的只是將文件校驗和附加到目標列表的末尾。


從源列表中創建一個散列或字典,然后你的新列表看起來像這樣。


//create dictionary SourceDictionary<string,string> with key = filepath.tolower and value = checksum

var newList = DestinationList.select(d => $"{d.thing1},{d.thingN}" + SourceDictionary[d.filename.tolower()])

應該快得多


查看完整回答
反對 回復 2023-04-29
  • 5 回答
  • 0 關注
  • 171 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號