2009-02-15 46 views
0

我有一個algorithm that compares two sorted lists,我打算讓它更LINQ-Y。命名一個比較兩個排序列表的算法?

我的第一個問題:LINQ中是否有這樣的東西?

如果沒有,我打算寫它作爲一個擴展方法,像這樣:

public static class SortedCompareExtension 
{ 
    public static IEnumerable<Pair<T, U>> 
     CompareTo<T,U>(this IEnumerable<T> left, 
         IEnumerable<U> right, 
         Func<T, U, int> comparison) 
    { /* ... */ } 
} 

它會返回new Pair<T, U>(t, u)如果兩個元素是等價的,new Pair<T, U>(t, null)如果元素只在左側存在手錶清單等

我的第二個問題:CompareTo不是一個偉大的名字。它是什麼?它是比較,整理,關聯?什麼?

回答

4

您是Synchronizing的列表,雖然名稱具有線程同步的不幸內涵。

我會說,「ReconcileOrdered」(也許OrderedReconcile)是一個合理的名稱(它可能是非常重要的函數的名稱,以表明該參數必須同時責令其正確的行爲

+0

我喜歡'協調'。我想我會去OrderedReconcileWith()。 – 2009-02-15 16:56:46

0

鏈接的算法非常接近「完全外部合併連接」。它僅在重複對待的方式上有所不同。

LINQ中是否有這樣的東西?

它會返回新的對(T,U)如果兩個元素是等價的,對新(T,NULL)如果元素只在左側列表不存在,等等

左只有一邊,GroupJoin是類似的。

1

如何Diff ?我不相信LINQ中已經有任何東西可以做,但是有ExceptIntersect。這聽起來像你的代碼大多是兩者的混合物 - 除了那些是設置操作,而你已經有了排序列表。它主要是一個效率的例子,還是在你的情況下有語義上的差異?(一個例子是重複的條目。)

就我個人而言,我不確定我會在這種情況下使用一對。只涉及一個價值,不是嗎? Value,PresentInLeft(bool)和PresentInRight(bool)不是真的嗎?我敢肯定,每種表示方式都有其優點和缺點,並且您肯定可以從相同的基礎數據中暴露任何API ...

+0

這是爲了提高效率。IEnumerable 實際上可能位於網絡連接的另一端(從服務器返回),並且可能非常大,因此我在協同程序中生成它們。 – 2009-02-15 16:54:14

0

下面是我最終得到的代碼。我很喜歡它,尤其是指主叫方可以決定如何在每個場景中返回的選擇:

public static class OrderedReconcileExtension 
{ 
    public static IEnumerable<TResult> 
     ReconcileWith<T, U, TResult>(this IEnumerable<T> left, 
            IEnumerable<U> right, 
            Func<T, U, int> comparison, 
            Func<T, U, TResult> selector) 
    { 
     return ReconcileHelper(new EnumerableIterator<T>(left), 
           new EnumerableIterator<U>(right), 
           comparison, selector); 
    } 

    private static IEnumerable<TResult> 
     ReconcileHelper<T, U, TResult>(EnumerableIterator<T> left, 
             EnumerableIterator<U> right, 
             Func<T, U, int> comparison, 
             Func<T, U, TResult> selector) 
    { 
     while (left.IsValid && right.IsValid) 
     { 
      // While left < right, the items in left aren't in right 
      while (left.IsValid && right.IsValid && 
        comparison(left.Current, right.Current) < 0) 
      { 
       yield return selector(left.Current, default(U)); 
       left.MoveNext(); 
      } 

      // While right < left, the items in right aren't in left 
      while (left.IsValid && right.IsValid && 
        comparison(left.Current, right.Current) > 0) 
      { 
       yield return selector(default(T), right.Current); 
       right.MoveNext(); 
      } 

      // While left == right, the items are in both 
      while (left.IsValid && right.IsValid && 
        comparison(left.Current, right.Current) == 0) 
      { 
       yield return selector(left.Current, right.Current); 
       left.MoveNext(); 
       right.MoveNext(); 
      } 
     } 

     // Mop up. 
     while (left.IsValid) 
     { 
      yield return selector(left.Current, default(U)); 
      left.MoveNext(); 
     } 

     while (right.IsValid) 
     { 
      yield return selector(default(T), right.Current); 
      right.MoveNext(); 
     } 
    } 
} 

EnumerableIterator是完全一樣的我張貼在其他問題的代碼。

更新:除了IsValid之外,「完全相同」更改爲HasCurrent。選一個。