Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proper way to modify Qt data structures using foreach loop [duplicate]

I am iterating through a QLinkedList using a foreach loop, but I need to delete items if they match a certain condition. What is the proper way to do this without messing up the loop?

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

I have found other questions that sort of address this, but not for the general case such as the linked list.

I would like to know also concerning other data structures (like QSet, QHash, etc.) if possible. Thanks

like image 673
Freedom_Ben Avatar asked Jul 05 '13 17:07

Freedom_Ben


1 Answers

For the specific case:

Apparently foreach loops should not be used to modify the list at all, because the foreach loop is actually working on a copy of the original list. If you modify it, not only do you incur a penalty because of the implicit-sharing and modify-on-write, but your changes are also discarded once you exit the loop.

The correct way to accomplish this is to use an iterator. I prefer the Java-style iterators. You'll notice that there are iterator classes for each list type that provide simple iterators. For the QLinkedList example, there is a class QMutableLinkedListIterator. It can be used as follows:

From the Qt documentation with my comments added:

 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
     }
 }


For the general case:

If you're using a Qt data structure other than QLinkedList, chances are good there's an iterator class for you. If you want to modify the list, use the Mutable version. The API is roughly the same for each of these. Here are the classes:

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
like image 134
Freedom_Ben Avatar answered Oct 06 '22 02:10

Freedom_Ben