2014-03-28 22 views
0

這不是您典型的合併。我基本上有2個或更多的集合,我需要合併和項目的順序是重要的。每個集合的實例都將具有相同順序的項目,但項目可能會或可能不會在集合中。爲了演示我將使用數字,但在實際應用中,這些是對象。c#合併列表,但基於相對於這兩個列表中的項目的位置

collection_1 = [3,5,7,9] 
collection_2 = [2,5,6] 
collection_3 = [1,2,3,4,7,8] 

After merge of collection 1 and 2 i am looking for 
[3,2,5,6,7,9] or [2,3,5,7,9,6] or [3,2,5,7,9,6] are all correct 
After merge above with collection 3 
[1,2,3,4,5,6,7,8,9] (other variations possible) 

這個想法是,我會給它一個集合一個接一個地合併,但它不需要中斷任何集合的順序。額外的項目可以在兩者之間添加,但順序必須相同。

我知道這是一個奇怪的情況,但它是用於代碼生成,其中類的屬性的順序必須是在一個特定的順序,所以他們得到序列化出來,他們進來了。如果一個屬性是沒有填充,那麼它不會被序列化,所以這就是爲什麼我可以在中間添加項目但不改變順序。爲了方便地以自動化的方式比較輸入和輸出,我需要它們以相同順序出來,否則它需要手動測試,我不想這樣做:)

---編輯---

試圖解釋它好一點。

我可以檢查的是,如果一個列表中的項目等於另一個列表中的項目。這些項目將不是上述數字的對象,也不能對其內容進行排序。排序/排序基於項目相對於兩個列表中的項目的順序。唯一能做到這一點的方法是知道一個列表是100%正確排列的,第二個列表是一個合併,因此可能會出現亂序。我的源列表將始終以相同的順序排列,所以當由於較早的合併而發生衝突時,可以將它們作爲真實點。

我也工作的一些可能的解決方案,但沒有運氣尚未

+1

我很困惑,你怎麼能有'集合中1'合併集合後1和2 – paqogomez

+1

這是很難理解您的需求。我沒有看到你如何確定3在第一次合併之前必須出現2,但在第二次合併之前2出現在3之前是可以的。你需要給我們一個更好的解釋。 –

+0

@paqogomez是啊,這是一個錯誤,我已經刪除它 – Seer

回答

0

如果我理解正確的,你應該使用HashSet的創建合併徵收,即使用排序後。所以你必須創建自定義比較器。 您的需求難以理解,但如果合併數組的順序基於合併前的順序,則可能會使用包裝器結構來存儲合併前的項目位置。

+0

不起作用。我只能檢查平等。如果你想把它們看作字符串或單詞,並且按順序排列,發現它們不是按字母順序排列的。我使用數字,因爲它使它更容易,或者我認爲它會。項目在列表中的順序是重要的,它們對列表中的項目的位置也是重要的。 – Seer

0

之後,我設法想出了以下方法來做到這一點。這不是完美的,但似乎95%的時間正確地得到訂單。對於那些感興趣的人來說,實施如下,如果任何人有更好的實施,我仍然感興趣。

public static List<T> OrderdMergeList<T>(this List<T> master, List<T> secondary) 
    { 
     var output = master.ToList(); 
     var itemsToInsert = new List<T>(); 
     int? lastMatchIndex = null; 
     foreach (var item in secondary) 
     { 
      if (output.Contains(item)) 
      { 
       if (!lastMatchIndex.HasValue) 
       { 
        //already in the list so insert any items we have before this and not already in the output 
        var index = output.IndexOf(item); 
        output.InsertRange(index, itemsToInsert); 
        itemsToInsert.Clear(); 
        lastMatchIndex = output.IndexOf(item);//updates it to new position 
       } 
       else 
       { 
        //already in the list but also already found a match so need to be careful for out of order info 
        var index = output.IndexOf(item); 
        if (index > lastMatchIndex.Value) 
        { 
         output.InsertRange(index, itemsToInsert); 
         itemsToInsert.Clear(); 
         lastMatchIndex = output.IndexOf(item); //updates it to new position 
        } 
        else 
        { 
         output.InsertRange(lastMatchIndex.Value+1, itemsToInsert); 
         if (itemsToInsert.Count > 0) 
         { 
          lastMatchIndex = output.IndexOf(itemsToInsert.Last()); //updates it to new position 
         } 
         else 
         { 
          lastMatchIndex += 1; 
         } 
         itemsToInsert.Clear(); 

        } 
       } 
      } 
      else 
      { 
       //not in the output so add it to the list to insert when we find a match 
       itemsToInsert.Add(item);   
      } 
     } 
     //insert any left over items on the end 
     output.AddRange(itemsToInsert); 
     return output; 
     //return master.Union(secondary).ToList(); 
    } 
相關問題