62 votes

Supprimer l'élément du vecteur pendant l'itération ?

J'ai un vecteur qui contient des éléments actifs ou inactifs. Je veux que la taille de ce vecteur reste petite pour les problèmes de performances, donc je veux que les éléments qui ont été marqués inactifs soient effacés du vecteur. J'ai essayé de le faire pendant l'itération, mais j'obtiens l'erreur "itérateurs vectoriels incompatibles".

 vector<Orb>::iterator i = orbsList.begin();

    while(i != orbsList.end()) {
        bool isActive = (*i).active;

        if(!isActive) {
            orbsList.erase(i++);
        }
        else {
            // do something with *i
            ++i;
        }
    }

72voto

Moo-Juice Points 22190

La façon la plus lisible que j'ai faite dans le passé est d'utiliser std::vector::erase combiné avec std::remove_if . Dans l'exemple ci-dessous, j'utilise cette combinaison pour supprimer tout nombre inférieur à 10 d'un vecteur.

( Pour les non-c++0x, vous pouvez simplement remplacer le lambda ci-dessous par votre propre prédicat :)

 // a list of ints
int myInts[] = {1, 7, 8, 4, 5, 10, 15, 22, 50. 29};
std::vector v(myInts, myInts + sizeof(myInts) / sizeof(int));

// get rid of anything < 10
v.erase(std::remove_if(v.begin(), v.end(), 
                       [](int i) { return i < 10; }), v.end());

59voto

VassilisGr Points 740

Je suis d'accord avec la réponse de wilx. Voici une implémentation :

 // curFiles is: vector < string > curFiles;

vector< string >::iterator it = curFiles.begin();

while(it != curFiles.end()) {

    if(aConditionIsMet) {

        it = curFiles.erase(it);
    }
    else ++it;
}

7voto

Pierre Points 559

erase renvoie un pointeur vers la prochaine valeur de l'itérateur (identique à Vassilis) :

 vector <cMyClass>::iterator mit
for(mit = myVec.begin(); mit != myVec.end(); )
{   if(condition)
        mit = myVec.erase(mit);
    else
        mit++;
}

4voto

Gelldur Points 1473

Si quelqu'un a besoin de travailler sur des index

 vector<int> vector;
for(int i=0;i<10;++i)vector.push_back(i);

int size = vector.size();
for (int i = 0; i < size; ++i)
{
    assert(i > -1 && i < (int)vector.size());
    if(vector[i] % 3 == 0)
    {
        printf("Removing %d, %d\n",vector[i],i);
        vector.erase(vector.begin() + i);
    }

    if (size != (int)vector.size())
    {
        --i;
        size = vector.size();
        printf("Go back %d\n",size);
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X