[Solved] Reading Key/Values from QHash



  • I have a hash table that stores a QString (Key) and QObject(value) .

    @QHash<QString,QObject *> hashTable;@

    here i can insert the values as

    @hashTable.insert("A",new QLabel("A"));
    hashTable.insert("C",new QLabel("C"));
    hashTable.insert("D",new QLabel("D"));
    hashTable.insert("F",new QLabel("F"));
    hashTable.insert("B",new QLabel("B"));
    hashTable.insert("G",new QLabel("G"));
    hashTable.insert("E",new QLabel("E"));@

    But while reading the keys from the hashTable using

    @foreach (QString string, hashTable.keys()) {

        qDebug()<<string;
    }@
    

    or

    @QHashIterator<QString, QObject*> i(hashTable);
    while(i.hasNext()) {
    i.next();
    qDebug()<<i.key();
    }@

    I get the output as

    @"D"
    "E"
    "F"
    "G"
    "A"
    "B"
    "C"@

    Which is not the order in which the keys were inserted to the hashTable.
    Is there any way to read the keys in the same way it is inserted?



  • A QHash does not keep the items in the order you inserted them. If you need that, use [[doc:QMap]] instead. If the order does not matter, prefer QHash as performs a bit better.



  • @Andre

    From the documentation of QHash , i got

    bq. QHash is unordered, so an iterator's sequence cannot be assumed to be predictable. If ordering by key is required, use a QMap.

    But in QMap it sorts the list based on the key, so output comes out to be

    @"A"
    "B"
    "C"
    "D"
    "E"
    "F"
    "G"@

    Which is not the order in which the key/values were inserted.

    Another approach i thought of is using a
    @QList</Structure (Struct)/>@

    where the Structure stores values as

    @struct ObjectList{
    QString name;
    QObject *object;
    };@

    or

    @QList<QPair<QString,QObject*> > // don't know if this will work n i don't prefer much to use it either@

    Which one should i use / any other approach to get the same.
    Thanks for the help :)



  • You could also just save the QObject in a QList<QObject*> and use objectName/setObjectName for the key. So when you search for an object, either use the built-in findChild of the objects parent or go through the list yourself and check the objectName properties.

    Otherwise I agree with your two methods, but would still turn the struct into a small class with Constructor that takes initialization values for the members.

    If you want fast access and keep the order (i.e. have > 10000 objects and access them by key regularly), combine a QHash (for fast access by key) with a QList<QString> (for storing the keys in an ordered fashion).



  • Ah, right, yes. A map is ordered by key, not by insertion. In your example it would have have mattered due to the two being the same, but you are right. Your idea of using a struct is good, if you cannot store the object name inline with the object. Personally, I prefer it over using QPair, because it results in more readable code. The QPair::first and QPair::second names are not all that informative about what actually is first and what is second. It will work though, you only need to add a space between the two >>'s (otherwise it is interpretted as a streaming operator). Typedefs would make the construct more readable, but still not great.

    So yes, creating a
    @
    struct ObjectNode
    {
    QString name;
    QObject* object;
    }

    typedef QList<ObjectNode> ObjectList;
    @
    is not a bad idea. If you still need lookups by name, you can then just add a
    @
    QHash<QString, int>
    @
    to keep track of the indexes in your list (or QVector, if you could use that instead of QList) for each name. If you insert a copy of the string, that doesn't waste too much space.



  • For now I'll stick to -creating a struct and storing it in a QList. As here the requirement is to load a frame/form whose values and specifications are provided in a xml file. So i need a container that contains both the key(name) and value(object).

    Thanks for your time :)
    This is solved.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.