2010-12-16 2 views
0

У меня есть список элементов для удаления из упорядоченной коллекции на C#.Каков наилучший способ удалить элементы из упорядоченной коллекции?

Каков наилучший способ обойти это?

Если я удалю элемент посередине, индекс изменится, но что, если я хочу удалить несколько элементов?

+0

Ваш список предметов, чтобы удалить отсортирован? – Vlad 2010-12-16 22:20:09

ответ

5

Чтобы избежать изменения индекса, начать в конце и идти в обратном направлении, чтобы индекс 0.

Что-то вдоль этих линий:

for(int i = myList.Count - 1; i >= 0; i++) 
{ 
    if(NeedToDelete(myList[i])) 
    { 
     myList.RemoveAt(i); 
    } 
} 
+0

Просто, чтобы добавить к этому, я думаю, что она означает начало с последнего элемента, который вы хотите удалить, и идите вверх. – BeemerGuy 2010-12-16 22:20:32

+0

@BeemerGuy: Я добавил образец кода, чтобы проиллюстрировать, что я имел в виду. – 2010-12-16 23:26:38

+0

О, хорошо, я думал, что оппортунистика опережает время. – BeemerGuy 2010-12-16 23:28:12

1

Какой тип коллекции? Если он наследует от ICollection, вы можете просто запустить цикл над списком элементов для удаления, а затем вызвать метод .Remove() в коллекции.

Для примера:

object[] itemsToDelete = GetObjectsToDeleteFromSomewhere(); 
ICollection<object> orderedCollection = GetCollectionFromSomewhere(); 

foreach (object item in itemsToDelete) 
{ 
    orderedCollection.Remove(item); 
} 
1

Если коллекция является List<T> вы также можете использовать RemoveAll метод:

list.RemoveAll(x => otherlist.Contains(x)); 
0

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

Предполагается, что список источника haystack и список элементов удаляемых needle:

needle.Sort(); // not needed if it's known that `needle` is sorted 
// haystack is known to be sorted 
haystackIdx = 0; 
needleIdx = 0; 
while (needleIdx < needle.Count && haystackIdx < haystack.Count) 
{ 
    if (haystack[haystackIdx] < needle[needleIdx]) 
     haystackIdx++; 
    else if (haystack[haystackIdx] > needle[needleIdx]) 
     needleIdx++; 
    else 
     haystack.RemoveAt(haystackIdx); 
} 

Таким образом, у вас есть только 1 обход как haystack и needle, плюс время сортировки needle, при условии, что удаление - O(1) (что часто бывает для связанных списков и подобных коллекций). Если коллекция является List<...>, удаление потребуется O(collection size) из-за сдвигов данных, так что лучше начать с конца обеих коллекций и перейти к началу:

needle.Sort(); // not needed if it's known that `needle` is sorted 
// haystack is known to be sorted 
haystackIdx = haystack.Count - 1; 
needleIdx = needle.Count - 1; 
while (needleIdx >= 0 && haystackIdx >= 0) 
{ 
    if (haystack[haystackIdx] > needle[needleIdx]) 
     haystackIdx--; 
    else if (haystack[haystackIdx] < needle[needleIdx]) 
     needleIdx--; 
    else 
     haystack.RemoveAt(haystackIdx--); 
} 
Смежные вопросы