2013-07-05 6 views
5

Ich bin durch eine QLinkedList mit einer foreach Schleife durchlaufen, aber ich muss Elemente löschen, wenn sie eine bestimmte Bedingung entsprechen. Was ist der richtige Weg, dies zu tun, ohne die Schleife durcheinander zu bringen?Korrekte Möglichkeit, Qt-Datenstrukturen mit foreach-Schleife zu ändern

foreach(Object obj, myLinkedList) 
{ 
    if(obj.val == BAD_VAL) 
     // remove the item from myLinkedList 
} 

Ich habe festgestellt other questions diese Art der Adresse dieser, aber nicht für den allgemeinen Fall wie die verknüpften Liste.

Ich würde gerne auch über andere Datenstrukturen (wie QSet, QHash, etc.) wenn möglich wissen. Dank

+0

@hyde Ich habe mich mit dieser Frage in meiner Frage verbunden und gesagt, dass sie nicht die Gesamtheit dessen anspricht, was ich gefragt habe. Es gibt einen Unterschied zwischen 'QList' und' QLinkedList'. Sie sind ähnlich, aber nicht identisch. –

+0

Nun, es beantwortet die Frage, soweit ich das beurteilen kann. Qt nimmt eine flache Kopie des Containers, wenn Sie seine 'foreach' verwenden. Wenn Sie die Struktur des ursprünglichen Containers ändern, muss Qt eine neue tiefe Kopie des vollständigen Containers erstellen (Kopie auf Schreibsemantik). Kurz gesagt, benutze 'foreach' nicht dafür. Und die Semantik ist für jeden Qt-Container gleich. – hyde

Antwort

14

Für den speziellen Fall:

Offenbar foreach Schleifen sollen nicht verwendet werden, die Liste überhaupt, weil die foreach Schleife tatsächlich zu ändern, ist auf einem Arbeitskopie der ursprünglichen Liste. Wenn Sie es ändern, entsteht nicht nur eine Strafe wegen des impliziten Teilens und Änderns beim Schreiben, sondern Ihre Änderungen werden auch verworfen, sobald Sie die Schleife verlassen.

Der richtige Weg, dies zu erreichen, ist die Verwendung eines Iterators. Ich bevorzuge die Java-Stil-Iteratoren. Sie werden feststellen, dass es für jeden Listentyp Iteratorklassen gibt, die einfache Iteratoren bereitstellen. Für das QLinkedList Beispiel gibt es eine Klasse QMutableLinkedListIterator.

Vom Qt documentation mit meinen Kommentaren hinzugefügt:

QMutableLinkedListIterator<int> i(list); // pass list as argument 
while (i.hasNext()) { 
    int val = i.next();     // retrieve value of current item 
    if (val < 0) { 
     i.setValue(-val);    // change/set value of current item 
    } else if (val == 0) { 
     i.remove();      // delete current item 
    } 
} 


Für den allgemeinen Fall: Es kann wie folgt verwendet werden

Wenn Sie eine Qt-Datenstruktur andere verwenden als QLinkedList, die Chancen stehen gut, es gibt eine Iterator-Klasse für Sie. Verwenden Sie die Mutable-Version, wenn Sie die Liste ändern möchten. Die API ist für jede von ihnen ungefähr gleich. Hier sind die Klassen:

Structure | Immutable Case  | Mutable Case 
----------------------------------------------------- 
QList  | QListIterator  | QMutableListIterator 
QLinkedList | QLinkedListIterator | QMutableLinkedListIterator 
QHash  | QHashIterator  | QMutableHashIterator 
QMap   | QMapIterator   | QMutableMapIterator 
QSet   | QSetIterator   | QMutableSetIterator 
QStringList | QStringListIterator | QMutableStringListIterator 
QVector  | QVectorIterator  | QMutableVectorIterator 
0

Ich kann auch vorschlagen, eine teure, aber einfache Möglichkeit, dies zu tun. Erstellen Sie eine andere Liste und kopieren Sie gute Objekte dazu. Ersetzen Sie dann die alte Liste durch eine neue.

Tun Sie dies nicht, wenn der Inhalt Ihrer Liste groß ist.

Verwandte Themen