137 votes

remove_if équivalent pour std::map

J'ai essayé d'effacer toute une gamme d'éléments de la carte en fonction d'une condition particulière. Comment puis-je le faire en utilisant des algorithmes de la STL?

J'ai d'abord pensé à utiliser remove_if mais il n'est pas possible que remove_if ne fonctionne pas pour conteneur associatif.

Est-il "remove_if" équivalent algorithme qui fonctionne pour la carte ?

Comme une simple option, j'ai pensé à une boucle dans la carte et de les effacer. Mais en parcourant la carte et l'effacement d'une option sécuritaire?(comme les itérateurs obtenir invalide après l'effacer)

J'ai utilisé l'exemple suivant:

bool predicate(const std::pair<int,std::string>& x)
{
    return x.first > 2;
}

int main(void) 
{

    std::map<int, std::string> aMap;

    aMap[2] = "two";
    aMap[3] = "three";
    aMap[4] = "four";
    aMap[5] = "five";
    aMap[6] = "six";

//      does not work, an error
//  std::remove_if(aMap.begin(), aMap.end(), predicate);

    std::map<int, std::string>::iterator iter = aMap.begin();
    std::map<int, std::string>::iterator endIter = aMap.end();

    for(; iter != endIter; ++iter)
    {
    		if(Some Condition)
    		{
                            // is it safe ?
    			aMap.erase(iter++);
    		}
    }

    return 0;
}

126voto

Steve Folly Points 2373

Presque.

for(; iter != endIter; ) {
            if (Some Condition) {
                    aMap.erase(iter++);
            } else {
                    ++iter;
            }
}

Ce que vous aviez à l'origine serait incrément de l'itérateur deux fois si vous n'avez effacer un élément, vous pourriez potentiellement sautez sur les éléments qui doivent être effacées.

Il s'agit d'un algorithme que j'ai vu utilisé et documenté dans de nombreux endroits.

[EDIT] il est exact que les itérateurs sont invalidées après un effacement, mais seulement itérateur référençant l'élément qui est effacé, les autres itérateurs sont toujours valables. Par conséquent, avec iter++ dans l'effacer() de l'appel.

83voto

Iron Savior Points 1100
<h2>erase_if pour std::map (et autres conteneurs)<p>J’utilise le modèle suivant pour cette chose.</p><pre><code></code></pre><p>Cela ne retourne rien, mais il va supprimer les éléments de la std::map.</p><p>Exemple d’utilisation :</p><pre><code></code></pre><p>Deuxième exemple (permet de passer une valeur de test) :</p><pre><code></code></pre></h2>

3voto

1800 INFORMATION Points 55907

J'ai eu cette documentation de l' excellent SGI STL référence:

La carte est la propriété la plus importante que l'insertion d'un nouvel élément dans une carte n'a pas pour effet d'invalider les itérateurs qui point aux éléments existants. L'effacement d'une élément à partir d'une carte aussi est-ce pas invalider les itérateurs, à l'exception, de bien sûr, pour les itérateurs qui en fait pointez sur l'élément qui est en cours de effacées.

Ainsi, l'itérateur vous avez qui pointe sur l'élément à effacer va bien sûr être invalidé. Faire quelque chose comme ceci:

if (some condition)
{
  iterator here=iter++;
  aMap.erase(here)
}

1voto

piotr Points 2826

De la notes de fond:

http://www.sgi.com/tech/stl/PairAssociativeContainer.html

une Paire Conteneur Associatif ne peut pas fournir mutable itérateurs (tel que défini dans le Trivial Itérateur exigences), parce que le type de la valeur d'une mutable itérateur doit être Cessible, et la paire n'est pas Cessible. Cependant, une Paire Conteneur Associatif peuvent fournir des itérateurs qui ne sont pas complètement constante: les itérateurs telle que l'expression (*i).deuxième = d est valide.

1voto

user109134 Points 159

Mon humble avis il n’y a aucun remove_if équivalent. Vous ne pouvez pas réorganiser une carte. Si remove_if ne peut pas mettre mettre vos paires d’intérêt à la fin à laquelle vous pouvez appeler effacer.

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