Friday, February 4, 2011

How do I remove an item from a stl vector with a certain value?

I was looking at the API documentation for stl vector, and noticed there was no method on the vector class that allowed the removal of an element with a certain value. This seems like a common operation, and it seems odd that there's no built in way to do this.

  • Use the global method std::remove with the begin and end iterator, and then use std::vector.erase to actually remove the elements.

    Documentation links
    std::remove http://www.cppreference.com/cppalgorithm/remove.html
    std::vector.erase http://www.cppreference.com/cppvector/erase.html

    std::vector<int> v;
    v.push_back(1);
    v.push_back(2);
    
    //Vector should contain the elements 1, 2
    
    //Find new end iterator
    std::vector<int>::iterator newEnd = std::remove(v.begin(), v.end(), 1);
    
    //Erase the "removed" elements.
    v.erase(newEnd, v.end());
    
    //Vector should now only contain 2
    

    Thanks to Jim Buck for pointing out my error.

  • See also std::remove_if to be able to use a predicate...

  • std::remove doesn't actually erase the element from the container, but it does return the new end iterator which can be passed to container_type::erase to do the REAL removal of the extra elements that are now at the end of the container:

    std::vector<int> vec;
    // .. put in some values ..
    int int_to_remove = n;
    vec.erase(std::remove(vec.begin(), vec.end(), int_to_remove), vec.end());
    
    From Jim Buck
  • G'day,

    I know I've mentioned this several times before but Scott Meyer's book Effective STL (Amazon link) covers these gotchas in a clear way.

    HTH.

    cheers, Rob

    From Rob Wells
  • If you have an unsorted vector, then you can simply swap with the last vector element then resize().

    With an ordered container, you'll be best off with std::vector::erase(). Note that there is a std::remove() defined in <algorithm>, but that doesn't actually do the erasing. (Read the documentation carefully).

    From nsanders
  • The other answers cover how to do this well, but I thought I'd also point out that it's not really odd that this isn't in the vector API: it's inefficient, linear search through the vector for the value, followed by a bunch of copying to remove it.

    If you're doing this operation intensively, it can be worth considering std::set instead for this reason.

0 comments:

Post a Comment