objetos - recorrer una lista c++
¿Cómo elimino un elemento de un vector stl con un cierto valor? (8)
Las otras respuestas cubren cómo hacerlo bien, pero pensé que también señalaría que no es realmente extraño que esto no esté en la API vectorial: es ineficiente, la búsqueda lineal a través del vector para el valor, seguida de un montón de copiar para eliminarlo.
Si está haciendo esta operación de manera intensiva, puede valer la pena considerar std :: set en su lugar por este motivo.
Estaba mirando la documentación de API para stl vector, y noté que no había ningún método en la clase vectorial que permitiera la eliminación de un elemento con un cierto valor. Esto parece una operación común, y parece extraño que no haya una forma de hacerlo.
Si desea eliminar un elemento, lo siguiente será un poco más eficiente.
std::vector<int> v;
auto it = std::find(v.begin(), v.end(), 5);
if(it != v.end())
v.erase(it);
o puede evitar la sobrecarga de mover los artículos si el pedido no le importa:
std::vector<int> 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();
}
Si quieres hacerlo sin ningún extra, incluye:
vector<IComponent*> 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;
}
}
}
}
Si tiene un vector sin clasificar, entonces simplemente puede intercambiar con el último elemento vectorial y luego resize()
.
Con un contenedor ordenado, lo mejor será con std std::vector::erase()
. Tenga en cuenta que hay un std::remove()
definido en <algorithm>
, pero eso no borra. (Lea la documentación cuidadosamente).
Una solución más corta (que no te obliga a repetir el nombre del vector 4 veces) sería usar Boost:
#include <boost/range/algorithm_ext/erase.hpp>
// ...
boost::remove_erase(vec, int_to_remove);
Utilice el método global std :: remove con el iterador de inicio y fin, y luego use std :: vector.erase para eliminar realmente los elementos.
Enlaces de documentación
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
Gracias a Jim Buck por señalar mi error.
Ver también std::remove_if para poder usar un predicado ...
Aquí está el ejemplo del enlace de arriba:
vector<int> 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<int>(cout, " "));
// The output is "1 4 2 8 5 7"
vector<int>::iterator new_end =
remove_if(V.begin(), V.end(),
compose1(bind2nd(equal_to<int>(), 0),
bind2nd(modulus<int>(), 2)));
V.erase(new_end, V.end()); [1]
copy(V.begin(), V.end(), ostream_iterator<int>(cout, " "));
// The output is "1 5 7".
std :: remove en realidad no borra el elemento del contenedor, pero devuelve el nuevo iterador final que se puede pasar a container_type :: erase para hacer la eliminación REAL de los elementos adicionales que están ahora al final del contenedor :
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());