2011-05-15 20 views
2

各リストに約60,000のオブジェクトが含まれている2つのリストを比較する必要があります。これを行う最も効率的な方法は何でしょうか?ソースリストにある、宛先リストに存在しないすべてのアイテムを選択したいとします。多くのオブジェクトを含む2つのリストの比較

私は、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); 
} 

私はこのクエリがいつまでかかりますか分かりません。私が利用できる他のものもあります。たとえば、ソースファイルが宛先ファイルと一致する場合、同じ名前と同じパスでファイル名を付けることはできないため、そのファイルと別の複製を持つことは不可能です。

答えて

4

、あなたが効率的にセットを比較するためにそれを使用することができ、タイプの等値比較子を作成します。

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のような方法でこれを使用することができ、または1つのリストではなく、他のない存在するすべてのアイテムを取得するためにExcept:メソッドはバケツにアイテムを分割するハッシュコードを使用することができたよう

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

を、に比べて行われる必要がはるかに少ない比較がありますそれがある場所への参加あるリストのすべてのアイテムを他のリストのすべてのアイテムと比較する。

4

LINQには、この目的のためにExcept()メソッドがあります。あなただけを使用することができますa.Except(b);

関連する問題