2012-06-14 54 views
0

所以我有一個'超級'列表:DestinationColumn,有100個字符串。總而言之,爲了簡單,總是100。將多個部分字符串列表與主字符串進行比較的模式

它來自ColA,ColB的幾個來源欄目。其中一些會有100個字符串,有些會少一些。

因此,例如:

可樂有串1-33,40-70,90-100和值。它首先獲得優先級,並將所有值填入DestinationColumn中以獲取這些字符串。 ColB的值爲1-40和70-100。如果有間隙存在,它會填滿它,但它不會纏繞ColA弦。

現在我想確保發生這種情況。

列出sourceColA,列出sourceColB 和ListdestinationColumn。

首先,我寫了一個函數來比較兩個列表,看看他們是否包含相同的字符串:

public static bool ListEquals<T>(IList<T> list1, IList<T> list2) 
    { 
     if ((list1 == null) || (list2 == null)) 
     { 
      return false; 
     } 
     if (list1.Count != list2.Count) 
      return false; 
     for (int i = list1.Count - 1; i >= 0; --i) 
     { 
      if (!list1[i].Equals(list2[i])) 
      { 
       return false; 
      } 
     } 
     return true; 
    } 

現在我想保持它作爲一般的作爲,但拍X源列,並確保所有內容現在正確地在一個目標列中。有這樣的一般模式嗎?

我目前的想法是一個循環,將colA的所有條目標記爲destinationCol,對B重複等等,然後確保所有條目都沒有被點擊兩次,並且所有條目都被命中了一次。

回答

1

要你描述你可以做盡可能簡單地

ColA.Zip(ColB, (a, b) => a??b) 

所以合併兩列:

void Main() 
{ 
    IEnumerable<IEnumerable<string>> cols= 
     new string[][] 
     { 
      new string[]{"monkey", "frog", null, null, null, null}, 
      new string[]{null, null, null, null, "cat", "giraffe"}, 
      new string[]{null, null, null, "dog", "fish", null} 
     }; 
    cols.MergeLeft().Dump(); 
    //gives: "monkey", "frog", null, "dog", "cat", "giraffe" 


} 

static class Ex 
{ 
    public static IEnumerable<T> MergeLeft<T> 
     (this IEnumerable<IEnumerable<T>> cols) where T:class 
    { 
     var maxItems = cols.Max(x => x.Count()); 
     var leftMerged = 
      cols 
       .Aggregate(
        Enumerable.Repeat((T)null, maxItems), 
        (acc,col) => acc.Zip(col, (a, b) => a ?? b)); 
     return leftMerged; 

    } 
} 

編輯

下面是MergeLeft更高效的版本不要求maxItems消除以下由@Enigmativity描述的費用:

static class Ex 
{ 
    public static IEnumerable<T> MergeLeft<T> 
     (this IEnumerable<IEnumerable<T>> cols) where T:class 
    { 
     return cols 
      .Aggregate(
       Enumerable.Empty<T>(), 
       (acc,col) => 
       acc 
        .Concat(Infinite<T>(null)) 
        .Zip(col, (a, b) => a ?? b)); 
    } 
    private static IEnumerable<T> Infinite<T>(T item) 
    { 
     for(;;){yield return item;} 
    } 
} 
+0

不錯的答案,不過'VAR maxItems'線是非常昂貴的,它可能有「熱」可枚舉該改變迭代之間的值。將'cols'推到一個數組可能是值得的,並且從第零列開始,作爲初始聚合累加器 - 然後'Zip'可以正常工作。 – Enigmativity

+0

@Enigmativity:看我的編輯 – spender

0

我不完全相信我明白你在做什麼,因爲我不明白你的ListEquals的目的。無論如何,我會去這樣:

public static void FillDest<T>(IList<T> dest, IList<IList<T>> srcLists) 
     where T : class 
    { 
     bool goon = true; 
     int idx = 0; 
     dest.Clear(); 
     while (goon) 
     { 
      goon = false; 
      bool added = true; 
      foreach (IList<T> aSrc in srcLists) 
      { 
       added = false; 
       T anItem; 
       if (aSrc.Count <= idx) 
       { 
        added = true; 
        continue; 
       } 
       goon = true; 
       if ((anItem = aSrc[idx]) != null) 
       { 
        dest.Add(anItem); 
        added = true; 
        break; 
       } 
      } 
      if (!added) 
       dest.Add((T)null); 
      idx++; 
     } 
    } 
相關問題