IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

std::map, effacer des éléments suivant un critère donné


Sujet :

C++

Vue hybride

guillaume07 std::map, effacer des... 18/01/2010, 12h41
Lavock Erase à besoin d'un iterator,... 18/01/2010, 12h50
guillaume07 J'utilise plusieurs map. Une... 18/01/2010, 12h56
3DArchi Salut, std::remove_if... 18/01/2010, 13h22
Arzar Presque correcte, la version... 18/01/2010, 14h07
guillaume07 perso, j'avais également ça... 18/01/2010, 14h11
Lightness1024 Il manquait au standard 98 le... 18/01/2010, 15h08
guillaume07 pourquoi ne pas farie ça : ... 18/01/2010, 16h20
Lavock Hum : <=> Si norme... 18/01/2010, 16h38
guillaume07 ty 18/01/2010, 17h29
Arzar Mais après 2003 aussi !... 18/01/2010, 18h01
Lavock Au temps pour moi, le... 18/01/2010, 18h20
3DArchi Effectivement, j'aurais mieux... 18/01/2010, 17h10
Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre très actif
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    688
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 688
    Par défaut std::map, effacer des éléments suivant un critère donné
    Salut,

    Quel est la bonne façon de faire pour effacer des éléments dans une map, suivant un critère du type chaine == "valeur".

    Est ce que cette façon est correct et performante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
            std::map<std::string,S>::const_iterator it;
            for(it=mapS.begin();it!=mapS.end();)
            {
                if( it->second.var41 == id )
                {
                    mapS.erase( it );
                }
                else
                    ++it;
            }
    y a t-il mieux?

    Merci.

  2. #2
    Membre chevronné Avatar de Lavock
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 560
    Par défaut
    Erase à besoin d'un iterator, pas d'un const_iterator.

    Ben c'est pas "mal", mais le concept est étrange... (et au passage certain vont raller car tu ne respect pas Demeter, mais c'est une autre histoire).

    D'habitude, la version erase(iterator) est peu utiliser. Mais alors là, parcourir la map jusqu'à trouver le bon... Quel est l'intérêt de la map ?

  3. #3
    Membre très actif
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    688
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 688
    Par défaut
    J'utilise plusieurs map.
    Une entrée d'une mapA peut contenir (entre autre) la clef d'une autre mapB.

    j'ai défois besoin d'effacer la clef de la mapB, ainsi que toutes les entrées des autres map qui contiennent cette clef

  4. #4
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Salut,
    Citation Envoyé par guillaume07 Voir le message
    y a t-il mieux?
    std::remove_if avec le bon prédicat.

  5. #5
    Membre Expert

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Par défaut
    Citation Envoyé par guillaume07 Voir le message
    Est ce que cette façon est correct et performante
    Presque correcte, la version idiomatique est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    for(; iter != endIter; ) 
    { 
       if(Some Condition) 
       { 
          aMap.erase(iter++); 
       } 
        else 
       { 
          ++iter; 
      } 
    }
    Citation Envoyé par 3DArchi
    std::remove_if avec le bon prédicat.
    Je ne crois pas qu'un remove_if (qui ne fait que déplacer des éléments) peut s'appliquer à une map.

  6. #6
    Membre très actif
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    688
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 688
    Par défaut
    Citation Envoyé par Arzar Voir le message
    Presque correcte, la version idiomatique est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    for(; iter != endIter; ) 
    { 
       if(Some Condition) 
       { 
          aMap.erase(iter++); 
       } 
        else 
       { 
          ++iter; 
      } 
    }


    Je ne crois pas qu'un remove_if (qui ne fait que déplacer des éléments) peut s'appliquer à une map.
    perso, j'avais également ça en tête.

  7. #7
    Membre éprouvé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    87
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2008
    Messages : 87
    Par défaut
    Il manquait au standard 98 le retour de l'itérateur suivant à l'operation erase() de std::map. Il a été rajouté au standard 03. C'est déjà pris en compte dans les unordered de boost. (attenion gcc/visual divergent aussi)
    remove_if ne devrait pas s'appeller comme ca car il ne fait pas du tout ce qu'on croit.

  8. #8
    Membre très actif
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    688
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 688
    Par défaut
    Citation Envoyé par Arzar Voir le message
    Presque correcte, la version idiomatique est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    for(; iter != endIter; ) 
    { 
       if(Some Condition) 
       { 
          aMap.erase(iter++); 
       } 
        else 
       { 
          ++iter; 
      } 
    }
    .
    pourquoi ne pas farie ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
     
    for(; iter != endIter; ) 
    { 
       if(Some Condition) 
       { 
          aMap.erase(iter); 
       } 
     
       ++iter; 
     
    }

  9. #9
    Membre chevronné Avatar de Lavock
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 560
    Par défaut
    Citation Envoyé par guillaume07
    pourquoi ne pas farie ça
    Hum :

    Citation Envoyé par Lightness1024 Voir le message
    Il manquait au standard 98 le retour de l'itérateur suivant à l'operation erase() de std::map. Il a été rajouté au standard 03. C'est déjà pris en compte dans les unordered de boost. (attenion gcc/visual divergent aussi)
    remove_if ne devrait pas s'appeller comme ca car il ne fait pas du tout ce qu'on croit.
    <=>

    Si norme > c++98, faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
     
    for(; iter != endIter; ++iter) 
    { 
       if(Some Condition)  
          aMap.erase(iter);   
    }
    sinon faire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
     
    for(; iter != endIter; ) 
    { 
       if(Some Condition) 
          aMap.erase(iter++); 
     
       else
           ++iter; 
    }
    Autrement dit, avant 2003, erase invalidé l'itérateur.

  10. #10
    Membre très actif
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    688
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 688
    Par défaut
    Citation Envoyé par Lavock Voir le message
    Hum :



    <=>

    Si norme > c++98, faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
     
    for(; iter != endIter; ++iter) 
    { 
       if(Some Condition)  
          aMap.erase(iter);   
    }
    sinon faire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
     
    for(; iter != endIter; ) 
    { 
       if(Some Condition) 
          aMap.erase(iter++); 
     
       else
           ++iter; 
    }
    Autrement dit, avant 2003, erase invalidé l'itérateur.
    ty

  11. #11
    Membre Expert

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Par défaut
    Citation Envoyé par Lavock Voir le message
    Autrement dit, avant 2003, erase invalidé l'itérateur.
    Mais après 2003 aussi !
    Avant 2003 il fallait faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    for(; iter != endIter; ) 
    { 
       if(Some Condition) 
          aMap.erase(iter++); 
        else
           ++iter; 
    }
    Après 2003, on peut maintenant faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    for(; iter != endIter; ) 
    { 
       if(Some Condition) 
          iter = aMap.erase(iter); 
        else
           ++iter; 
    }
    La correction de 2003 a permis d'aligner la méthode erase des map avec celles des autres conteneurs - en renvoyant l'itérateur valide qui suit celui venant d'être tout juste invalidé.

    Et tant mieux, car le trick du aMap.erase(iter++) en C++98 était vraiment pas évident.

  12. #12
    Membre chevronné Avatar de Lavock
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 560
    Par défaut
    Au temps pour moi, le prototype est bien iterator erase(iterator), et non void erase(iterator) >< !

  13. #13
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par Arzar Voir le message
    Je ne crois pas qu'un remove_if (qui ne fait que déplacer des éléments) peut s'appliquer à une map.
    Effectivement, j'aurais mieux fait de faire tourner 7 fois mon pouce autour de l'autre avant de répondre. On va mettre ça sur le dos d'une digestion soporifique.

Discussions similaires

  1. [Joomla!] Effacer des modules suivant la section
    Par lovoo dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 1
    Dernier message: 22/08/2008, 01h33
  2. [multi map] supprimer des éléments
    Par poukill dans le forum SL & STL
    Réponses: 3
    Dernier message: 22/05/2007, 12h17
  3. [multi map] supprimer des éléments
    Par poukill dans le forum C++
    Réponses: 3
    Dernier message: 22/05/2007, 12h17
  4. Effacer des éléments sur click
    Par hugo1992 dans le forum AWT/Swing
    Réponses: 3
    Dernier message: 22/03/2007, 16h22
  5. Effacer des éléments graphiques
    Par benjiprog dans le forum AWT/Swing
    Réponses: 4
    Dernier message: 08/09/2006, 13h44

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo