stl map key löschen
-
für was das gut ist?
hier z.b. ein .ini file
[blub1] key1=value key2=value .. .. [blub2] key1=asdfa key123=qwe5 ... ..
Jetzt lese ich das ini file ein. und dann kann ich die verschienden key bearbeiten. diese zeige ich an. bei änderungen löschungen ect bekommen die eine andere farbe in meiner gui. am schluss nachdem ich fertig bin, kann ich das ini file ( oder die daten aus der db ) wieder schreiben und da schaue ich nach.
wenn z.b. blub1 das flag( die farbe ) gelöscht hat ( z.b. rot ) dann lösche aus db.
bei farbe rot z.b. bei blub2 der key123 dann lösche diesen. ich habe eine spezielle datenstruktur dieblub + alle key von blub + alle value von blub + farbe von blub + farbe von key beinhaltet. Ich möchte nach allen operationen erst am schluss in DB oder file schreiben.
und warum soll da eine map schlecht sein bitte?
-
Es tut mir leid, aber du bist es, der nicht versteht, fürchte ich
Mir ist schon klar, dass du die innere Map mit dem Iterator durchsuchst. ABER: Du durchsuchst sie nach dem WERT, nämlich dem int. Und das ist nicht unbedingt das, was man mit einer Map macht
Was nicht heißt, dass es nicht durchaus ok sein, aber deswegen habe ich nach der Verwendung der Map gefragt.
Trotzdem, wenn du es tun willst, solltest du meinen Code verwenden, er tut nämlich genau das, was du willst: Er löscht bei Übereinstimmung des Wertes mit deinem Parameter das Element, auf das dein Iterator momentan zeigt, erhöht aber gleichzeitig den Iterator (wodurch er seine Gültigkeit behält). Und nur, falls der Wert deinem Kriterium nicht entspricht, wird der Iterator sonst erhöht.
Dein Code tut das folgende: Wenn das momentane Element deinem Kriterium entspricht, dann erstellst du eine Kopie des Iterators und erhöhst kc. Dann löschst du das Element, auf das die Kopie zeigt. Bis hierhin ist das mit meinem Code identisch, außer, dass ich es kompakter geschrieben habe
Aber: Nun verlässt dein Code die Bedingungsschleife und erhöht kc nochmal! Damit überspringst du ein Element, das nun nie geprüft wird. Geh das mal im Kopf durch, es ist wirklich so
-
sorry wenn ich doch falsch liege. aber es passt so bei mir. die werte die ich ein und aus lese stimmen. ich lade die key und values ein von einer anderen datenstruktur und in meiner "map" habe ich nur key+farbe gespeichert. wenn ich da nicht korekt lösche oder einfüge hängt es ja. da ich ja sage
schreibe key/value in box
suche jetzt key in map 2 wenn gefunden dann hat die zeile die farbe von int wenn nicht zeige schwarz an. in meiner box kommt schwarz nie vor. also müsste alles passenwo erstelle ich nach dem suchkriterium eine kopie?
ich weise nur einem CString zu und erhöhe und lösche dann.kannst mir das nochmal hinschreiben? denn vielleicht hast du nicht gesehen, dass dein code nicht geht, wegen dem Error! Also, so wie du es hingeschrieben hast, compiliert er nicht, deswegen kann ich auch nicht testen.
-
Ok, stell dir vor, du hast eine deiner inneren Maps (map2) mit folgenden Inhalten:
key1 -> 1
key2 -> 2
key3 -> 2
key4 -> 15Das ist also die Map, auf die dein iterator p (bzw. pointer p1) gerade zeigt. Nehmen wir weiter an, m_meinsuchwert = 2. Dann schauen wir mal, was passiert:
MyType::iterator kc; kc = p->second->begin(); // setze auf anfang while ( kc != p->second->end() ) // gehe alle key's in der 2ten map durch { if( kc->second == m_meinsuchwert ) // wenn wert gefunden { CString copy = kc->first; kc++; // zeige auf nächsten p1->erase(copy); // lösche // lösche von mapzeiger } ++kc; }
Erster Durchlauf der while-Schleife: if-Bedingung nicht erfüllt, da kc->second == 1 != 2 ist. if wird übersprungen, kc wird um eins erhöht und zeigt jetzt auf den Eintrag key2. Klar?
Zweiter Durchlauf: if-Bedingung ist ERFÜLLT, Code springt in die if-Schleife: Hier passiert jetzt folgendes: Du speicherst den Key des Iterators zwischen in copy. Dann erhöhst du den Iterator kc. Diesr zeigt jetzt in diesem Moment auf key3, logisch. Nun löschst du den gefundenen Eintrag mit seinem Key (meine Methode löscht ihn per Iterator, was schneller ist).
Ok, if-Block wird verlassen, und was passiert jetzt? Genau: kc wird NOCHMAL erhöht und zeigt jetzt auf key4! Mit diesem wird jetzt der dritte Durchlauf gestartet.key3 wurde aber nie angeschaut! Dummerweise hat key3 einen Wert gespeichert, der deinem Suchkriterium entspricht -> Fehler!
Verständlich?
-
Übrigens, der Fehler in meinem Code ist natürlich ein blöder Flüchtigkeitsfehler. So wäre er richtig:
if( kc->second == m_meinsuchwert ) // wenn wert gefunden p1->erase(kc++); // lösche // lösche von mapzeiger else ++kc;
-
argggggggggghhhhhhhhhhhhhhhhh
mein fehler soooooooooooooory
und danke für deine mühe
ihc habe das
else{ // <----------- dieses else habe ich vergessen. in meinem code hatte ich es schon nur hier im forum nicht :( ++kc; }
sooooorrrryyyyyyyyyyyyyyyyy
danke für die mühe. ich habs nicht gecheckt, das die else bed. hier nicht enthalten war
in meinem projekt aber schon
i know, kann passieren.
-
ok deine variante geht auch
aber auch nur weil ich dasMyType *p1 = p->second; // hier ZEIGER auf map
noch hingeschrieben habe. mit dem p oder mit dem mapnamen geht nicht
( wie du ja im urpost gehabt hast
)
-
Ok, dann war's ein Missverständnis, wenn du die else-Bedingung hattest. Klar, das merkt man dann auch nicht und redet aneinander vorbei
Ich würde dir aber empfehlen, den Iterator zum Löschen zu verwenden (wie in meinem Beispiel), nicht den Key, wie du es tust. Den Key muss die Map ja erst wieder suchen, und dadurch machst du der Map quasi doppelte Arbeit, wenn du den korrekten Iterator eh schon hast
-
maplover schrieb:
(Tipp: füge zwei mal den Suchwert ein für Keys die aufeinander folgen
)
Ich würd an deiner stelle stl map nochmals durcharbeiten
maplover schrieb:
ne map kann keinen doppelten key eintrag haben, per definition schon. deshalb kann ich gar keinen key 2 mal einfügen
Lern lesen. ("Keys die aufeinander folgen")
maplover schrieb:
ist keine multimap. deshalb kann ich einfach nach dem key suchen und ihn als wert löschen
Auch wenn's nicht allzu viel Sinn macht so zu verfahren wenn du den Iterator schon hast, ja, stimmt. Allerdings kannst du das bei einer multimap (m.m.) auch, und wo versteckt sich der Zusammenhang zu meinem Post?
maplover schrieb:
ich habe gerade die map schon getestet. key einfügen, löschen, mehrere löschen ( letzte/erste ) alle löschen usw.
und die map passte immer,Naja, wenn DU keinen Fehler entdecken konntest dann muss es ja korrekt sein, hm?
maplover schrieb:
weiss jetzt wirklich nicht warum nur in den hälften der fälle lieber @finix
Mein erneuter Rat: Lern lesen. Ich habe nirgends von der Hälfte der Fälle gesprochen.
Und ganz nebenbei macht es sich glaub ich nicht allzu toll sich so blasiert und herablassend zu geben wenn man Hilfe sucht, unabhängig davon ob man Recht oder, wie du, lieber @maplover, Unrecht hat.
-
Mit einigen Leuten sollte man sich hier nicht anlegen, weil sie immer Recht haben.
z.B. HumeSikkins, Bashar, Finix, Ponto, MFK ......