Element aus vektor löschen
-
Hallo,
Ich möchte einen Vektor durchsuchen und bei einem Treffer die Vektorstelle löschen.
Ich würde gerne mal wissen ob das hier so falsch funktioniert wie ich es mir gerade vorstelle:if(files.at(i).find(pattern) == string::npos) { files.erase(files.begin()+i); }
Das würde jetzt doch den vektor durchsuchen, und bei einem Fund danach ein objekt überspringen richtig?
also ich suche nach "c" und habe einen vektor:
a
b
c <- Fund --> lösche (begin + 2)"neuer" Vektor, Suche geht weiter:
a
b
d
e << einstieg weil i mittlerweile 3 ist. Das d wurde übersprungen.
fist das richtig? und btw, wie würd mans richtig machen?
Gruß,
Chris
-
Nein, das sieht ziemlich falsch aus.
Es gibt das Erase-Remove-Idiom:std::vector<Foo> vec = {...}; vec.erase(std::remove(std::begin(vec), std::end(vec), value), std::end(vec));
Wahlweise auch mit Remove_If und einem Funktor/Lambda.
-
alles klar, danke!
-
cl90 schrieb:
if(files.at(i).find(pattern) == string::npos) { files.erase(files.begin()+i); }
Das würde jetzt doch den vektor durchsuchen, und bei einem Fund danach ein objekt überspringen richtig?
Das wäre sehr ineffizient, wenn du das in einer Schleife über i machen würdest, weil jedes mal, wo ein Element gelöscht wird, alle anderen nachrücken müssen. Das kann man auch in einem Rutsch vernünftig machen, wie schon angedeutet wurde:
files.erase( std::remove_if(files.begin(),files.end(),[&](string const& x){ return x.find(pattern) != string::npos; }), files.end());
Hier wird jedes Element, was übrig bleiben soll, per
remove_if
höchstens einmal auf einen neuen Platz verschoben. Der Kram, der am Ende steht und nicht mehr benötigt wird, wird mit einer einzigen Aktion pererase
gelöscht.
-
je nach Container, könnte es so ein remove_if als Elementfunktion geben. Falls man z.B. eine std::list vor sich hat, sollte man lieber std::list<>::remove_if nehmen. Da werden wahrscheinlich nur ein paar Zeiger umgebogen, statt dass da Elemente von einem Listenknoten in einen anderen Listenknoten kopiert werden.