c++qtc++14qlistqmap

How do iterate QMap in other QMap


I look for on how to iterate a QMap in a other QMap like:

QMap<int, QMap<int, QString>> map;

Previously I used simple C++ std::map with the following code and that worked:

for(auto it = this->liste.begin(); it != this->liste.end(); it++) {
    for(auto itr = it->second.begin(); itr != it->second.end(); itr++) {
        //It works !!!!!
        //qDebug() << "First : " << itr->first;
        //qDebug() << "Second : " << itr->second;

        //d.setPath(itr->second);

        //qDebug() << "Path :" << itr->second << " Prefix :" << this->prefix << " Nb :" << itr->first;
        process(d.absolutePath(), this->prefix, itr->first);

        this->liste.clear();
    }
}

My question is how I could use QMap instead of std::map in order to use the QMap in a QTreeView with a foreach loop (in particularly for the QList with the items).

What is the replacement for liste.first and liste.second?

Edit:

std::map<int, std::map<int, QString>> liste;

Thanks!


Solution

  • You can use QMap::keys() with QMap::value() or QMap::operator[] to iterate over the list to keys and then use keys to get the values. Another solution could be just to get an std::map from QMap::toStdMap() and iterate over it using range-for loop.

    You might want to look at QMap::uniqueKeys() also depending on your use-case.


    UPDATE:

    As mentioned in the answer by cuda12, you can also make use of QMapIterator or QMutableMapIterator whichever you need to employ Java-style iterators but it is less efficient than the STL-style iterators. And, it doesn't answer your requirement of using foreach or range-for.

    Here's a quote from its documentation:

    The Java-style iterators are more high-level and easier to use than the STL-style iterators; on the other hand, they are slightly less efficient.


    Here's a working example:

    #include <QDebug>
    #include <QMap>
    #include <QMapIterator>
    #include <QString>
    
    int main()
    {
        using InnerMap = QMap<int, QString>;
        using OuterMap = QMap<int, InnerMap>;
    
        const OuterMap outerMap
        {
            { 1, {{ 11, "a" }, { 12, "aa" }} },
            { 2, {{ 22, "b" }, { 21, "bb" }} },
            { 3, {{ 22, "c" }} }
        };
    
        qDebug() << "--- foreach (QMap) ---";
    
        foreach ( const auto& outerKey, outerMap.keys() )
        {
            qDebug() << outerKey;
    
            const auto& innerMap = outerMap[ outerKey ];
            foreach ( const auto& innerKey, innerMap.keys() )
            {
                const auto& innerValue = innerMap[ innerKey ];
                qDebug() << "\t{" << innerKey << "," << innerValue << "}";
            }
        }
    
        qDebug() << "\n--- range-for (QMap -> std::map) ---";
    
        const auto& m1 = outerMap.toStdMap();
        for ( const auto& p1 : m1 )
        {
            qDebug() << p1.first;
    
            const auto& m2 = p1.second.toStdMap();
            for ( const auto& p2 : m2 )
            {
                qDebug() << "\t{" << p2.first << "," << p2.second << "}";
            }
        }
    
        qDebug() << "\n--- while (QMapIterator) ---";
    
        QMapIterator<int, InnerMap> outerIt{ outerMap };
        while ( outerIt.hasNext() )
        {
            outerIt.next();
            qDebug() << outerIt.key();
    
            QMapIterator<int, QString> innerIt{ outerIt.value() };
            while ( innerIt.hasNext() )
            {
                innerIt.next();
                qDebug() << "\t{" << innerIt.key() << "," << innerIt.value() << "}";
            }
        }
    
        return 0;
    }
    

    Output:

    --- foreach (QMap) ---
    1
            { 11 , "a" }
            { 12 , "aa" }
    2
            { 21 , "bb" }
            { 22 , "b" }
    3
            { 22 , "c" }
    
    --- range-for (QMap -> std::map) ---
    1
            { 11 , "a" }
            { 12 , "aa" }
    2
            { 21 , "bb" }
            { 22 , "b" }
    3
            { 22 , "c" }
    
    --- while (QMapIterator) ---
    1
            { 11 , "a" }
            { 12 , "aa" }
    2
            { 21 , "bb" }
            { 22 , "b" }
    3
            { 22 , "c" }