开发者

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--);
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜