2011-08-03 62 views
2

我需要確定兩個EntityCollections是否相等。我有代碼我認爲會做到這一點,但我想知道是否有更有效的算法?請注意,EntityCollections每個可能少於10個元素。有沒有更有效的方法來確定兩個EntityCollections是否包含相同的元素?

private static bool isEquivalent(
     EntityCollection<MyClassDetails> myClassDetails1, 
     EntityCollection<MyClassDetails> myClassDetails2) 
    { 
     var myClassComparer = new MyClassComparer(); 

     return 
      myClassDetails1.All(
       myClassDetail1 => 
       myClassDetails2.Contains(
        myClassDetail1, myClassComparer)); 
    } 

    class MyClassComparer : IEqualityComparer<MyClassDetails> 
    { 
     public bool Equals(MyClassDetails details1, MyClassDetails details2) 
     { 
      return details1.DetailID == details2.DetailID; 
     } 

     public int GetHashCode(MyClassDetails obj) 
     { 
      return obj.GetHashCode(); 
     } 
    } 
+0

這不會確定兩個集合的交集是否爲空? – dlev

+0

是的,我相信它。 – Don

回答

0

首先,如果你的集合可能只有10個元素,那麼擔心此算法的效率可能爲時過早,除非你在關鍵路徑中調用它很多。但您可以嘗試的一件事是使用Intersects和Any擴展。

return !myClassDetails1.Intersects(myClassDetails2, new MyClassComparer()).Any(); 

我不知道這將是多麼有效得多,但代碼會更漂亮。而且,在過去,我已經爲這種場合創建了一個FuncComparer。

class FuncComparer<T> : IEqualityComparer<T> 
{ 
    private Func<bool, T, T> compare; 
    public FuncComparer(Func<boo, T, T> compare){ 
    this.compare = compare; 
    } 
    public bool Equals(T left, T right) { 
    return this.compare(left, right); 
    } 
} 

// usage 
return !items1 
    .Intersects(items2, new FuncComparer<Item>((l, r) => l.Id == r.Id)) 
    .Any(); 
+0

不應該爲你的FuncComparer實現gethashcode嗎? – saus

+0

我喜歡這個解決方案,這可能是@ dlev的評論所暗指的。我認爲它的效率會降低,因爲它總是遍歷所有元素,但對於我期望的少量元素,它可能不會成爲問題。 – Don

+0

這不應該在發生故障時迭代每個元素。任何()將立即停止,如果從interestects返回單個項目,它將不會繼續迭代。相交也不需要在它返回之前完全迭代。這是共同慣例的力量。 –

0

我敢肯定,你將遍歷數組遍歷你的主循環(.All)。如果您使用linq對它們進行排序(orderby),則可以循環訪問一個列表,並將該項目與另一個列表中相同索引處的項目進行比較。事實上,只要你有所作爲,你可以返回false

+0

這是一個好點。如果我可以在兩個集合上都有服務器OrderBy DetailID,那麼只要我發現有所不同,我就可以返回。 – Don

+2

不,All()方法將在第一次失敗後停止迭代。 –

+0

會得到服務器訂購列表提高包含的性能? –

相關問題