2015-12-29 78 views
-3

我有一個實現,我需要循環通過文檔集合並基於一定條件合併文檔。如何合併列表中的項目<>集合C#

合併條件非常簡單,如果存在的文檔的文檔類型與後面的文檔的文檔類型相同,則從後面的文檔類型中複製所有頁面,並將其附加到當前文檔的頁面,並從集合中刪除後面的文檔。 注意:response.documentsresponse.documents[].pages都是列表<>集合。

我正在嘗試這個,但得到下面的異常一旦我刪除文檔。

集合被修改枚舉可以不執行

下面是代碼:

int docindex = 0; 
foreach(var document in response.documents) 
{ 
    string presentDoctype = string.Empty; 
    string laterDoctype = string.Empty; 

    presentDoctype = response.documents[docindex].doctype; 
    laterDoctype = response.documents[docindex + 1].doctype; 

    if (laterDoctype == presentDoctype) 
    { 
     response.documents[docindex].pages.AddRange(response.documents[docindex + 1].pages); 
     response.documents.RemoveAt(docindex + 1); 
    } 
    docindex = docindex + 1; 
} 

例:

reponse.documents[0].doctype = "BankStatement" //page count = 1 
reponse.documents[1].doctype = "BankStatement" //page count = 2 
reponse.documents[2].doctype = "BankStatement" //page count = 2 
reponse.documents[3].doctype = "BankStatement" //page count = 1 
reponse.documents[4].doctype = "BankStatement" //page count = 4 

預期結果:

response.documents[0].doctype = "BankStatement" //page count = 10 

請建議。讚賞您的幫助。

+1

您收到枚舉錯誤,因爲您更改了集合,因此枚舉器會失效。使用簡單的for循環代替foreach。 – ViRuSTriNiTy

+1

我建議先搜索錯誤消息 - 即https://www.bing.com/search?q=C%23+collection+was+modified+enumeration+may+not+execute,這應該會給你帶來好處許多基本的.Net例外的問題的解釋。這也可以讓你改善你的問題,解釋爲什麼標準方法不適合你(即使用'for'和仔細索引而不是'foreach')。 –

回答

2

我建議你看看LINQ GroupByDistinct處理您response.documents

實例(因爲我不能使用你的類,我給例如使用我自己定義的類):

假設你有DummyClass

public class DummyClass { 
    public int DummyInt; 
    public string DummyString; 
    public double DummyDouble; 
    public DummyClass() { 

    } 
    public DummyClass(int dummyInt, string dummyString, double dummyDouble) { 
     DummyInt = dummyInt; 
     DummyString = dummyString; 
     DummyDouble = dummyDouble; 
    } 
} 

然後做GroupBy如圖所示,

DummyClass dc1 = new DummyClass(1, "This dummy", 2.0); 
DummyClass dc2 = new DummyClass(2, "That dummy", 2.0); 
DummyClass dc3 = new DummyClass(1, "These dummies", 2.0); 
DummyClass dc4 = new DummyClass(2, "Those dummies", 2.0); 
DummyClass dc5 = new DummyClass(3, "The dummies", 2.0); 
List<DummyClass> dummyList = new List<DummyClass>() { dc1, dc2, dc3, dc4, dc5 }; 
var groupedDummy = dummyList.GroupBy(x => x.DummyInt).ToList(); 

將創建三個組,標誌着DummyInt

然後處理組,你可以做

for (int i = 0; i < groupedDummy.Count; ++i){ 
    foreach (DummyClass dummy in groupedDummy[i]) { //this will process the (i-1)-th group 
     //do something on this group 
     //groupedDummy[0] will consists of "this" and "these", [1] "that" and "those", while [2] "the" 
     //Try it out! 
    } 
} 

對於您的情況,您應該根據doctype創建組。

一旦您根據您的doctype創建羣組,其他任何事情對您而言都是非常「自然的」。

您可能感興趣的另一個LINQ方法是Distinct。但我認爲這種情況下,GroupBy將是您想要使用的主要方法。

+0

你可以舉一些例子說明如何去做。 – Fabjan

+1

@Fabjan示例添加 – Ian

0

僅使用「for循環」而不是「foreach」。

foreach將保存集合,並且無法在循環時通過它進行修改。

-3

只需使用的AddRange()

response.documents[0].pages.AddRange(response.documents[1].pages); 

將合併的文檔中的所有頁面[1]與文獻[0]到文件[0]

+0

他已經做到了。 –

0

這裏是一個使用groupBy的例子,希望對您有所幫助。

//mock a collection 
     ICollection<string> collection1 = new List<string>(); 
     for (int i = 0; i < 10; i++) 
     { 
      collection1.Add("BankStatement"); 
     } 
     for (int i = 0; i < 5; i++) 
     { 
      collection1.Add("BankStatement2"); 
     } 
     for (int i = 0; i < 4; i++) 
     { 
      collection1.Add("BankStatement3"); 
     } 

     //merge and get count 
     var result = collection1.GroupBy(c => c).Select(c => new { name = c.First(), count = c.Count().ToString() }).ToList(); 

     foreach (var item in result) 
     { 
      Console.WriteLine(item.name + ": " + item.count); 
     }