簡體   English   中英

比較包含大量對象的兩個列表

[英]Compare two lists that contain a lot of objects

我需要比較兩個列表,其中每個列表包含大約60,000個對象。 這樣做最有效的方法是什么? 我想選擇源列表中目標列表中不存在的所有項目。

我正在創建一個同步應用程序,其中c#掃描目錄並將每個文件的屬性放在列表中。 因此,有一個源目錄列表和目標目錄的另一個列表。 然后,我只是比較列表,看看哪些不同,而不是復制所有文件。 如果兩個列表都有相同的文件,那么我將不會復制該文件。 這是我使用的Linq查詢,它在掃描小文件夾時有效,但在掃描大文件夾時卻沒有。

// s.linst is the list of the source files
// d.list is the list of the files contained in the destination folder
  var q = from a in s.lstFiles
        from b in d.lstFiles
        where
        a.compareName == b.compareName &&
        a.size == b.size &&
        a.dateCreated == b.dateCreated
        select a;

// create a list to hold the items that are the same later select the outer join
List<Classes.MyPathInfo.MyFile> tempList = new List<Classes.MyPathInfo.MyFile>();

foreach (Classes.MyPathInfo.MyFile file in q)
{
    tempList.Add(file);
}

我不知道為什么這個查詢需要永遠。 還有其他我可以利用的東西。 例如,我知道如果源文件與目標文件匹配,則不可能與該文件有另一個副本,因為不可能具有相同名稱和相同路徑的文件名。

為此,LINQ有一個Except()方法。 你可以使用a.Except(b);

為該類型創建一個相等比較器,然后您可以使用它來有效地比較這些集:

public class MyFileComparer : IEqualityComparer<MyFile> {

  public bool Equals(MyFile a, MyFile b) {
    return
      a.compareName == b.compareName &&
      a.size == b.size &&
      a.dateCreated == b.dateCreated;
  }

  public int GetHashCode(MyFile a) {
    return
     (a.compareName.GetHashCode() * 251 + a.size.GetHashCode()) * 251 +
      a.dateCreated.GetHashCode();
  }

}

現在,您可以將此方法與Intersect方法一起使用以獲取兩個列表中存在的所有項目,或者Except獲取一個列表中存在但不存在另一個列表的所有項目:

List<MyFile> tempList =
  s.lstFiles.Intersect(d.lstFiles, new MyFileComparer()).ToList();

由於這些方法可以使用哈希代碼將項目划分為存儲桶,因此與連接相比,需要進行的比較要少得多,因為連接必須將一個列表中的所有項目與另一個列表中的所有項目進行比較。

使用Except()並閱讀有關使用linq的 set操作和使用HashSet設置操作的更多信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM