Jump to content
  • Advertisement
Sign in to follow this  
riruilo

[solved] erase an element from a std::vector with a specific position.

This topic is 3322 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi dudes! I know I can delete an element (or several) from a std::vector with a condition like this:
for(std::vector<type_sequence_and_frames>::iterator i=m_sequences.begin(); i!=m_sequences.end(); i++){
	if((*i).sequence_name.compare(sequence_to_remove)==0) {
		m_sequences.erase(i);
		break;
	}
}
But my question is: How can I delete, for instance, element in the 2nd position (without copying to an aux vector, of course)? Thanks for help. [Edited by - ricardo_ruiz_lopez on May 16, 2009 12:02:48 PM]

Share this post


Link to post
Share on other sites
Advertisement
The std::vector iterator supports addition with an int as rvalue. Thus, by getting the iterator of the first element through std::vector<T>::begin(), and adding the index i, you get the iterator of the ith element.

Share this post


Link to post
Share on other sites
Here's one way to do it:
v.erase(v.begin() + element_index);
Depending on how you're determining which element to erase, there may be more straightforward methods you could use (for example, if you're finding the element by searching for it manually, you could use std::find(), which returns an iterator).

[Too slow x 3.]

Share this post


Link to post
Share on other sites
Quote:
Original post by ricardo_ruiz_lopez
But my question is: How can I delete, for instance, element in the 2nd position (without copying to an aux vector, of course)?
Several other posters have shown you how you can accomplish this, but a better question might be whether you should do this.

Recall that std::vector uses contiguous storage, and as such, erasing any element apart from the last causes all following elements to be copied backwards one place. In particular, for your example of deleting the second item in a vector of N elements, this requires N-2 copy operations.

This is of course very expensive for large values of N, and/or if individual items in the vector are large or otherwise expensive to copy.



If you don't care about the order of items in the vector, you can use a very fast alternate method:
std::swap( my_vector[2], my_vector.back() );
my_vector.pop_back()

Share this post


Link to post
Share on other sites
Of course, there is also an easier-to-get-right and faster way to remove several elements:


struct is_named {
std::string name;
is_named(const std::string& name): name(name) {}
// By the way, you should almost never use '.compare()' for std::string.
// It makes things needlessly complicated.
bool operator()(const type_sequence_and_frames& data) {
return data.sequence_name == name;
}
};

// ...

m_sequences.erase(std::remove_if(m_sequences.begin(), m_sequences.end(), is_named(sequence_to_remove)), m_sequences.end());


And also an easier-to-get-right way to remove the first matching element:


// is_named defined as before
std::vector<type_sequence_and_frames>::iterator i = std::find_if(m_sequences.begin(), m_sequences.end(), is_named(sequence_to_remove));
if (i != m_sequences.end()) { m_sequences.erase(i); }

Share this post


Link to post
Share on other sites
Though if order doesn't matter and if you're dealing with a type that's expensive to copy but relatively cheap to swap (like containers of containers) you might want to use partition() rather than remove_if().

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!