2010-07-26 1 views
2

У меня есть строка Collection, заполняемая с ID как так ->Получить текущий индекс для удаления в Струнных коллекциях

12345 
23456 
34567 

и так далее. Мне нужно сделать это по запросу пользователя, и когда будут выполнены определенные параметры, просмотрите этот список, начиная с вершины, и выполните метод(), используя этот идентификатор. В случае успеха я удалю его из списка и перейду дальше.

Я, смущающе, никогда раньше не работал с коллекцией таким образом. Может кто-то указать мне в правильном направлении. Примеры, похоже, относятся к разнообразию Console.Writeline("");.

Моя база, невежественная, попытка выглядит так ->

var driUps = Settings.Default.DRIUpdates.GetEnumerator(); 
     while (driUps.MoveNext()) 
     { 
      var wasSuccessfull = PerformDRIUpdate(driUps.Current); 
      if (wasSuccessfull) 
      { 
       driUps.Current.Remove(driUps.Current.IndexOf(driUps.Current)); 
      } 
     } 

Часть меня больше всего волнует это Remove(); Не есть ли лучший способ, чтобы получить индекс текущего? Любые советы, подсказки, критика, указатели и т. Д. Приветствуются. Благодаря!

ответ

4

Вы совершенно правы, чтобы беспокоиться об «удалении» во время перечисления. Как насчет somethign, как это:

int idx = 0; 
while (idx < strCol.Count) 
{ 
    var wasSuccessful = PerformDRIUpdate(strCol[idx]); 
    if (wasSuccessful) 
     strCol.RemoveAt(idx); 
    else 
     ++idx; 
} 
+0

Это также позволяет избежать проблемы с аннулированием перечислителя при удалении элемента из коллекции. +1 – TreDubZedd

+1

+1 для обеспечения решения, которое не использует перечислитель, для «изменения, измененного в процессе перечисления». В зависимости от размера коллекции, но я обычно зацикливаю их назад по соображениям производительности, чтобы предотвратить повторное построение внутренней коллекции. –

+0

@chibacity: Перемещаясь назад, вы «поменяете» условие «while», по существу? И 'idx = strCol.Count'? –

0

Итерация перечислитель лучше всего делать с Еогеасп(), он делает GetEnumerator() и создает подобный блок под одеялом к ​​тому, что вы получаете в, синтаксис :

foreach(ObjectType objectInstance in objectInstanceCollection) 
{ 
    do something to object instance; 
} 

для вас,

List<DRIUpdate> updatesToRemove = new List<DRIUpdate>(); 
foreach(DRIUpdate driUpdate in Settings.Default.DRIUpdates) 
{ 
    if (PerformDRIUpdate(driUpdate)) 
    { 
     updatesToRemove.Add(driUpdate); 
    } 
} 

foreach(DRIUpdate driUpdate in updatesToRemove) 
{ 
    Settings.Default.DRIUpdates.Remove(driUpdate); 
} 
0

Если driUps является IEnumerable<T>, попробуйте следующее:

driUps = driUps.Where(elem => !PerformDRIUpdate(elem)); 

Update:

Из примера, кажется, это более уместно:

Settings.Default.DRIUpdates = 
    Settings.Default.DRIUpdates.Where(elem => !PerformDRIUpdate(elem)); 

Для List<T>, это проще:

list.RemoveAll(PerformDRIUpdate); 
1

По предложению n8wrl, использование RemoveAt решает проблему удаления элемента при перечислении коллекции, но для большого коллекционирования ns, удаляющие элементы с фронта, могут вызвать проблемы с производительностью, поскольку базовая коллекция будет перестроена. Проделайте свой путь с конца коллекции и удалите предметы с этого конца:

//Loop backwards, as removing from the beginning 
//causes underlying collection to be re-built 
int index = (strCol.Count - 1); 

while (index >= 0) 
{ 
    if (PerformDRIUpdate(strCol[index])) 
    { 
     strCol.RemoveAt(index); 
    } 

    --index; 
} 
+0

Спасибо, не проблема для меня, так как этот список больше никогда не будет, скажем, 20 пунктов, но всегда хорошо знать «лучшую практику». Мне жаль, что мне не удалось получить половину ответов.Во всяком случае, спасибо, что нашли время. –

+0

@Refracted Это было бы хорошо. Просто счастлива передать знания :) –