2015-12-29 2 views
-3

У меня есть реализация, когда мне нужно перебирать коллекцию документов и на основе определенного условия объединять документы.Как объединить элементы в списке <> коллекции C#

Условие слияния очень просто, если документ doctype этого документа аналогичен документу документа документа, а затем скопируйте все страницы из более позднего типа и добавьте его на страницы настоящего документа и удалите из коллекции более поздний документ. Примечание: Оба response.documents и response.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; 
} 

Ex:

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 GroupBy и Distinct обработать ваш 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

Используйте только «для петли» вместо «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); 
     } 
Смежные вопросы