alxcyl
alxcyl

Reputation: 2722

Deleting an object in a vector

I am trying to delete an element in a vector of Objects. The vector is filled with instances of Object and at some point, I want to remove a certain element in a vector not by index, but by the element itself.

A simple example would be:

std::vector< string > strVector;
strVector.push_back( "abc" );
strVector.push_back( "def" );
strVector.push_back( "ghi" ); // So strVector should contain "abc", "def", and "ghi"

How do I remove "ghi" from that vector? Note that I don't know where "ghi" is in that vector.

// Something like this. Assume strVector = [ "abc", "cba", "ccb", "bac", "aaa" ]
strVector.removeElement( "ccb" );

A more relevant example to what I a working on:

class MyClass {
   std::vector< Object > myObjVector;
   void main( ARGS ) {
      for ( int i = 0; i < 10; i++ ) {
         Object myObject = Object( );
         myObjVector.push_back( myObject );
      }

      int j = getANumber( ); // j could be any number within the size of the vector
      Object myOtherObject = myObjectVector.at( j );

      // How do I erase myOtherObject (which is an object inside the vector) ?
      removeFromVector( myOtherObject );
   }
}

I hope the question's clear. Thanks in advance.

EDIT: I figured it out, thanks to all those who answered. The trick was to give the class something unique that identifies it (like a name or a tag, as long as they are guaranteed to be unique) then use the erase-remove idiom to remove the object from the array.

Upvotes: 1

Views: 558

Answers (4)

juanchopanza
juanchopanza

Reputation: 227418

If your use-case has no duplicates, then you are better off using an std::set and using the std::set::erase which takes a value.

std::set< string > strSet;
strSet.insert( "abc" );
strSet.insert( "def" );
strSet.insert( "ghi" );
strSet.insert( "ccb" );

strSet.erase("ccb");

If you need to cope with duplicates, then you have to specify the desired behaviour of the removal. Should it remove one or all of the elements matching a value? Do you care about preserving the order of the remaining elements? If you require using a vector, then lokk at the erase-remove idiom. But note that std::vector::erase has linear time complexity, whereas the relevant variant of std::set::erase has logarithmic time complexity. And erase-remove would remove all elements equal to the given value.

Note: if you want to use an std::set for a user defined type, you must provide either a less-than bool operator<(const UserType&) const or a comparison function or functor, implementing strict weak ordering.

Upvotes: 6

James Kanze
James Kanze

Reputation: 153919

If the objects in the vector support equality, and that's the condition for removal, then you can use:

v.erase( std::remove( v.begin(), v.end(), "ghi" ), v.end() );

Otherwise, you'll need remove_if, with a functional object (or lambda, if you have C++11) which returns true if the element is to be removed.

Upvotes: 1

Lwin Htoo Ko
Lwin Htoo Ko

Reputation: 2406

#include <iostream>
#include <vector>

class Object
{
public:
    Object(int n){secret_num = n;}
    virtual ~Object(){}
    int getSecretNum(){return secret_num;}

private:
    int secret_num;
};

int main()
{

    int index= -1;
    Object *urobj = new Object(104);
    std::vector<Object*> urvector;

    for(int i = 0; i < 10; ++i)
    {
       Object *obj = new Object(i+1);
       urvector.push_back(obj);

    }

    urvector.push_back(urobj);

    for(int j = 0; j < urvector.size(); ++j)
    {
        Object *tmp = urvector.at(j);
        std::cout << tmp->getSecretNum() << std::endl;
        if(urobj == tmp)
            index = j; 
    }

    if(index == -1)
       std::cout << " not match " << std::endl;
    else 
       std::cout << " match " << index << std::endl;

    return 0;
}

Upvotes: 0

hmjd
hmjd

Reputation: 121971

If you must use a vector, then use erase(remove()):

#include <algorithm>
#include <string>
#include <vector>

strVector.erase(std::remove(strVector.begin(), strVector.end(), "ghi"),
                strVector.end());

this will remove all instances of "ghi" from strVector.

Upvotes: 4

Related Questions