What's the best way to remove items from an ordered collection?
I have a list of items to remove from an ordered collection in C#.
what's the best way in going about t开发者_运维技巧his?
If I remove an item in the middle, the index changes but what If I want to remove multiple items?
To avoid index changes, start at the end and go backwards to index 0.
Something along these lines:
for(int i = myList.Count - 1; i >= 0; i++)
{
if(NeedToDelete(myList[i]))
{
myList.RemoveAt(i);
}
}
What is the type of the collection? If it inherits from ICollection, you can just run a loop over the list of items to remove, then call the .Remove()
method on the collection.
For Example:
object[] itemsToDelete = GetObjectsToDeleteFromSomewhere();
ICollection<object> orderedCollection = GetCollectionFromSomewhere();
foreach (object item in itemsToDelete)
{
orderedCollection.Remove(item);
}
If the collection is a List<T>
you can also use the RemoveAll method:
list.RemoveAll(x => otherlist.Contains(x));
Assuming that the list of items to delete is relatively short, you can first sort the target list. Than traverse the source list and keep an index in the target list which corresponds to the item which you deleted.
Supposed that the source list is haystack
and list of items to delete is 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);
}
This way you have only 1 traversal of both haystack
and needle
, plus the time of sorting the needle
, provided the deletion is O(1)
(which is often the case for linked lists and the collections like that). If the collection is a List<...>
, deletion will need O(collection size)
because of data shifts, so you'd better start from the end of both collections and move to the beginning:
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--);
}
精彩评论