2009-07-23 2 views
2

У меня есть список строк из набора данных, который мне нужно перебирать.Как перебирать список, который изменяется?

Проблема в том, что обработка на итерации может удалить одну или несколько строк из списка.

Поскольку список изменяется, я не могу использовать цикл foreach().

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

Как бы вы справились с этой проблемой? Мое настоящее подумало, что всегда обрабатывать первый элемент в списке. Если он удаляется, обработайте новый первый элемент. Если он не удаляется, переместите его в список «уже обработанный» и обработайте новый первый элемент.

Есть ли более простой способ?

ответ

2

При изменении списка я перебор, я всегда нахожу, что проще построить новый список с деталями, которые я хочу сохранить, а затем использовать новый список, чтобы сделать то, что это я собирался делать.

Это действительно зависит от того, что вы делаете с данными, когда закончите, я полагаю.

+0

Это направление, к которому я склоняюсь. Спасибо за подтверждение. –

8

Обычно это делается с обратной петлей:

List<string> Items = ... 
for(int i = Items.Count - 1; i >= 0; i--) 
{ 
    if(Items[i] == "DELETE ME") 
    { 
     Items.RemoveAt(i); 
    } 
} 

Это приводит к тому, элементы должны быть обработаны в обратном порядке, так что если вы удалите элемент, он не влияет на позицию каких-либо предметов по-прежнему будет обработанный.

+0

Это не будет работать в том случае, если я рассматриваю, потому что удаление может происходить не только в элементе i, но и в другом элементе i +/- n, что означает, что i-- может указывать или не указывать в правильном следующем элементе. Кроме того, удаление нескольких элементов может потенциально оставить i или даже i--, указывая на объект, который уже не существует, за пределами списка. (Заметим также, что я не обязательно знаю, сколько элементов могло быть удалено.) –

0
for(int i = list.Length -1, i >= 0; i--) 
{ 
    // process and delete if you want 
} 
+0

Просьба объявить 'i' – Dario

+0

Смотрите мой комментарий к Дэвиду выше. –

0


int i = 0; 
while (i < dataSet.Tables[0].Rows.Count) { 
    if (some_condition) { 
     dataSet.Tables[0].Rows.RemoveAt(i); 
     continue; 
    } 
    i++; 
} 
+0

Если происходит несколько удалений (условие, которое я не могу легко узнать), то i (или i ++) не будет указывать на правильный следующий элемент. (Причина, по которой может произойти более одного удаления, связана с каскадным удалением в отношении «один ко многим».) –

+0

Да, если вы удалите (не удалите) строку. Но мой пример удаляет строки из DataTable. Если вы используете Delete(), вы можете проверить RowState == RowState.Deleted каждой строки в вашем цикле. –

0

Если вы можете получить свои данные в связанном списке, вы будете золотыми.

Смежные вопросы