Comment supprimer un élément d’un vecteur stl avec une certaine valeur?

Je regardais la documentation de l’API pour stl vector et j’ai remarqué qu’il n’existait aucune méthode sur la classe vectorielle permettant de supprimer un élément avec une certaine valeur. Cela semble être une opération commune et il semble étrange qu’il n’y ait pas de moyen de le faire.

std :: remove n’efface pas réellement l’élément du conteneur, mais renvoie le nouvel iterator final qui peut être passé à container_type :: erase pour effectuer la suppression REAL des éléments supplémentaires qui se trouvent maintenant à la fin du conteneur :

std::vector vec; // .. put in some values .. int int_to_remove = n; vec.erase(std::remove(vec.begin(), vec.end(), int_to_remove), vec.end()); 

Si vous souhaitez supprimer un élément, les éléments suivants seront un peu plus efficaces.

 std::vector v; auto it = std::find(v.begin(), v.end(), 5); if(it != v.end()) v.erase(it); 

ou vous pouvez éviter de déplacer les articles si la commande n’a pas d’importance pour vous:

 std::vector v; auto it = std::find(v.begin(), v.end(), 5); if (it != v.end()) { using std::swap; // swap the one to be removed with the last element // and remove the item at the end of the container // to prevent moving all items after '5' by one swap(*it, v.back()); v.pop_back(); } 

Utilisez la méthode globale std :: remove avec l’iterator begin et end, puis utilisez std :: vector.erase pour supprimer les éléments.

Liens de documentation
std :: remove http://www.cppreference.com/cppalgorithm/remove.html
std :: vector.erase http://www.cppreference.com/cppvector/erase.html

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

Merci à Jim Buck pour avoir signalé mon erreur.

Les autres réponses expliquent comment bien faire cela, mais je pensais aussi que ce n’est pas vraiment étrange que ce ne soit pas dans l’API vectorielle: c’est inefficace, la recherche linéaire à travers le vecteur pour la valeur, suivie par un tas de copier pour le supprimer.

Si vous effectuez cette opération de manière intensive, il peut être utile de considérer std :: set pour cette raison.

Si vous avez un vecteur non sortingé, vous pouvez simplement permuter avec le dernier élément vectoriel puis le resize() .

Avec un conteneur ordonné, vous serez mieux avec ‍ std std::vector::erase() . Notez qu’il y a un std::remove() défini dans , mais cela ne fait pas réellement l’effacement. (Lisez attentivement la documentation).

Voir aussi std :: remove_if pour pouvoir utiliser un prédicat …

Voici l’exemple du lien ci-dessus:

 vector V; V.push_back(1); V.push_back(4); V.push_back(2); V.push_back(8); V.push_back(5); V.push_back(7); copy(V.begin(), V.end(), ostream_iterator(cout, " ")); // The output is "1 4 2 8 5 7" vector::iterator new_end = remove_if(V.begin(), V.end(), compose1(bind2nd(equal_to(), 0), bind2nd(modulus(), 2))); V.erase(new_end, V.end()); [1] copy(V.begin(), V.end(), ostream_iterator(cout, " ")); // The output is "1 5 7". 

Une solution plus courte (qui ne vous oblige pas à répéter le nom du vecteur 4 fois) serait d’utiliser Boost:

 #include  // ... boost::remove_erase(vec, int_to_remove); 

Voir http://www.boost.org/doc/libs/1_64_0/libs/range/doc/html/range/reference/algorithms/new/remove_erase.html

Si vous voulez le faire sans aucun supplément, veuillez inclure:

 vector myComponents; //assume it has items in it already. void RemoveComponent(IComponent* componentToRemove) { IComponent* juggler; if (componentToRemove != NULL) { for (int currComponentIndex = 0; currComponentIndex < myComponents.size(); currComponentIndex++) { if (componentToRemove == myComponents[currComponentIndex]) { //Since we don't care about order, swap with the last element, then delete it. juggler = myComponents[currComponentIndex]; myComponents[currComponentIndex] = myComponents[myComponents.size() - 1]; myComponents[myComponents.size() - 1] = juggler; //Remove it from memory and let the vector know too. myComponents.pop_back(); delete juggler; } } } }