22

If I have

vector<T> list 

Where each element in the list is unique, what's the easiest way of deleting an element provided that I don't know if it's in the list or not? I don't know the index of the element and I don't care if it's not on the list.

5
  • 2
    Why the name of a vector container is list .. It could be confusing, a lot (for someone, that reads your code) Commented Oct 3, 2011 at 7:12
  • 1
    @KirilKirov, I don't think list is a reserved keyword in C++? Even so, it's just an example. Commented Oct 3, 2011 at 7:13
  • It is a container type, just as vector is. And both are pretty different :) Commented Oct 3, 2011 at 7:15
  • is this a homework question or are you trying to solve a specific problem? if the latter describing the problem may give you alternative solutions, if the former you should tag it as homework Commented Oct 3, 2011 at 7:16
  • 3
    If all elements in your container must be unique and you don't need to use its index, you probably should use std::set<T> instead of vector. Commented Oct 3, 2011 at 7:35

4 Answers 4

33

You could use the Erase-remove idiom for std::vector

Quote:

std::vector<int> v; // fill it up somehow v.erase(std::remove(v.begin(), v.end(), 99), v.end()); // really remove all elements with value 99 

Or, if you're sure, that it is unique, just iterate through the vector and erase the found element. Something like:

for( std::vector<T>::iterator iter = v.begin(); iter != v.end(); ++iter ) { if( *iter == VALUE ) { v.erase( iter ); break; } } 
Sign up to request clarification or add additional context in comments.

4 Comments

I would note that you can use find_if() instead of straight iterations.
Your 2nd answer .. I wouldn't do it this way. To extend to delete ALL occurrences of VALUE would trip people up in 2 possible places: iter is invalidated after .erase(), and ++iter would fail immediately. Would have to write iter=v.erase(iter); instead. Now if you do it that way, an extra ++iter will be committed after an erasure, skipping elements. To fix this you should always iterate backwards through the vector when deleting elements. Using a numerical index will fix these problems. for( int i = v.size()-1; i >= 0; i-- ) if( v[i]==VALUE ) v.erase( v.begin()+i ) ;
I know, but I said "to extend to delete"
@bobobobo - true, but this is another answer, does not make my answer wrong.
3

Based on Kiril's answer, you can use this function in your code :

template<typename T> inline void remove(vector<T> & v, const T & item) { v.erase(std::remove(v.begin(), v.end(), item), v.end()); } 

And use it like this

remove(myVector, anItem); 

Comments

3

If occurrences are unique, then you should be using std::set<T>, not std::vector<T>.

This has the added benefit of an erase member function, which does what you want.

See how using the correct container for the job provides you with more expressive tools?

#include <set> #include <iostream> int main() { std::set<int> notAList{1,2,3,4,5}; for (auto el : notAList) std::cout << el << ' '; std::cout << '\n'; notAList.erase(4); for (auto el : notAList) std::cout << el << ' '; std::cout << '\n'; } // 1 2 3 4 5 // 1 2 3 5 

Live demo

1 Comment

A vector is used for a reason, e.g. preserving the insert order. so If occurrences are unique, then you should be using std::set<T>, not std::vector<T> is nowhere valid. Let's just focus on the OP's settings.
1

From c++20

//LIKE YOU MENTIONED EACH ELEMENT IS UNIQUE std::vector<int> v = { 2,4,6,8,10 }; //C++20 UNIFORM ERASE FUNCTION (REMOVE_ERASE IDIOM IN ONE FUNCTION) std::erase(v, 8); //REMOVES 8 FROM VECTOR 

Now try

std::erase(v, 12); 

Nothing will happen, the vector remains intact.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.