[ERLEDIGT] Mehrere Elemente aus einer Map löschen.



  • Hallo Leute, ich habe eine Map die Pair Elemente speichert.
    Das zweite ist eine Klasse die eine startknot_id und eine endknot_id speichert.

    Jetzt möchte ich eine Funktion implementieren die unter angabe einer bestimmten id alle Elemente löscht die diese ID im startknot oder endknot haben.

    typedef std::map<unsigned int,Edge, std::less<unsigned int>>::iterator EDGE_ITERATOR;
    
    EDGE_ITERATOR edgeit;
    for(edgeit=edges.begin();edgeit!=edges.end();edgeit++){
    	if((edgeit->second.get_startknot_id()==useless_id) || (edgeit->second.get_endknot_id()==useless_id)){
    			edges.erase(edgeit);
    	}
    }
    

    Die get_... Funktionen liefern die richtigen Ergebnisse. Leider hängt sich diese Schleife schon im ersten Durchgang in Zeile 6 auf. Warum ist es so?



  • Weil der Iterator ungültig ist nach dem erase.



  • darkfate schrieb:

    Die get_... Funktionen liefern die richtigen Ergebnisse. Leider hängt sich diese Schleife schon im ersten Durchgang in Zeile 6 auf. Warum ist es so?

    Weil edgeit ungültig wird, wenn du das Element, auf das er zeigt, aus der Map entfernst. Da du aber im Schleifenkopf darauf immer edgeit++ aufrufst geht das dann schief.

    Schau dir am Besten mal std::remove_if an 🙂



  • Fellhuhn schrieb:

    Weil der Iterator ungültig ist nach dem erase.

    Sowas ähnliches habe ich mir auch schon gedacht. Wie könnte man es lösen?
    Ich habe es mit einer do while Schleife angefangen.. ist aber noch nicht fertig.



  • pumuckl schrieb:

    darkfate schrieb:

    Die get_... Funktionen liefern die richtigen Ergebnisse. Leider hängt sich diese Schleife schon im ersten Durchgang in Zeile 6 auf. Warum ist es so?

    Weil edgeit ungültig wird, wenn du das Element, auf das er zeigt, aus der Map entfernst. Da du aber im Schleifenkopf darauf immer edgeit++ aufrufst geht das dann schief.

    Schau dir am Besten mal std::remove_if an 🙂

    Danke für den Tipp. Irgendwie kriege ich es nicht hin diese Funktion auf meine map anzuwenden. HAbe jetzt edgeit = edges.begin(); hinzugefügt:

    EDGE_ITERATOR edgeit;
    for(edgeit=edges.begin();edgeit!=edges.end();edgeit++){
    	if((edgeit->second.get_startknot_id()==useless_id) || (edgeit->second.get_endknot_id()==useless_id)){
    			edges.erase(edgeit);
    			edgeit = edges.begin();
    	}
    }
    

    Es klappt nun einwandfrei. Wenn du Zeit hättest, könntest du mir bitte Zeigen wie ich die remove_if Funktion auf diese Situation anwende? Bereits implementierte Sachen habe ich lieber als eigenen code zu produzieren.



  • Kannst folgendes machen:

    for (std::map<int, std::string>::iterator i = m_map.begin(), e = m_map.end(); i != e; )
    {
        if (condition)
            m_map.erase(i++);
        else
            ++i;
    }
    

    Wichtig ist das i++ bei erase, da so i nach dem erase wieder valide ist.



  • Fellhuhn schrieb:

    ....

    Danke, habe ich übernommen. code ist noch kürzer. Interessant wäre dennoch die remove_if Funktion weil ich an mehreren Stellen solche Schleifen verwende.



  • Ich glaube remove_if funktioniert nicht mit std::map, bin mir aber nicht sicher.

    Ansosten wäre es einfach:

    std::remove_if(map.begin(), map.end(), einFunktorEtc);
    


  • Fellhuhn schrieb:

    Ich glaube remove_if funktioniert nicht mit std::map, bin mir aber nicht sicher.

    Ansosten wäre es einfach:

    std::remove_if(map.begin(), map.end(), einFunktorEtc);
    

    Klappt leider nicht bei map. Steht zumindest so in den meisten Foreneinträgen. Da es funktioniert, bin ich auch so glücklich, danke.



  • darkfate schrieb:

    Klappt leider nicht bei map. Steht zumindest so in den meisten Foreneinträgen.

    Stimmt, tut mir leid. remove_if ist auf sequenz-Container beschränkt und funktioniert nicht mit assoziativen Containern. Asche auf mein Haupt.



  • pumuckl schrieb:

    darkfate schrieb:

    Klappt leider nicht bei map. Steht zumindest so in den meisten Foreneinträgen.

    Stimmt, tut mir leid. remove_if ist auf sequenz-Container beschränkt und funktioniert nicht mit assoziativen Containern. Asche auf mein Haupt.

    Für Hilfe braucht man sich zu entschuldigen. Dank dir kenne ich eine Abkürzung falls ich mal mit vector etc arbeite 🙂


Anmelden zum Antworten