Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QHash behaviour
Qt 6.11 is out! See what's new in the release blog

QHash behaviour

Scheduled Pinned Locked Moved General and Desktop
24 Posts 5 Posters 23.8k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • ? Offline
    ? Offline
    A Former User
    wrote on last edited by
    #1

    Hi guys,

    I want to create a not ordered list organized in pairs. In order to achieve that I used a QHash as follows:

    @
    QHash<int,QString> lista;
    QHash<int,QString>::const_iterator i;
    lista[3] = "Three";
    lista[2] = "Two";
    lista[1] = "One";
    i = lista.constBegin();
    while(i != lista.constEnd())
    {
    qDebug() << i.key() << i.value();
    i++;
    }
    @

    But it's writing a key ordered list:

    1 "One"
    2 "Two"
    3 "Three"

    instead of:

    3 "Three"
    2 "Two"
    1 "One"

    What am I doing wrong?

    Thanks.

    1 Reply Last reply
    0
    • A Offline
      A Offline
      andre
      wrote on last edited by
      #2

      The order of QHash is undefined. That does not mean that there is no order, just that Qt doesn't guarantee any particular order for you to rely on. If you want a create a non-ordered list, why do you care in which order your results are printed?

      1 Reply Last reply
      0
      • M Offline
        M Offline
        mlong
        wrote on last edited by
        #3

        QHash, as you noted, is unordered. This means that that iterating over it will return the results in an arbitrary order, not necessarily the order in which you inserted them.

        So, I would maintain that you're not doing anything wrong, except perhaps expecting the wrong results.

        What are you trying to accomplish? If you're wanting a container where you can insert arbitrarily-paired objects in a certain order and always fetch them in that order, you could consider using something like
        @QList< QPair<int, QString> >@ which would preserve the sequence in which you inserted the pairs of objects.

        Or, if you're still needing random access to the items, you could insert them into the hash as you are currently doing and additionally keep a QList of the keys in the order in which you inserted them.

        Software Engineer
        My views and opinions do not necessarily reflect those of anyone -- living or dead, real or fictional -- in this universe or any other similar multiverse node. Void where prohibited. Your mileage may vary. Caveat emptor.

        1 Reply Last reply
        0
        • ? Offline
          ? Offline
          A Former User
          wrote on last edited by
          #4

          Xm..
          When i run app at first time i get: 3,2,1;
          Then:2,3,1;
          Then:3,2,1;

          1 Reply Last reply
          0
          • A Offline
            A Offline
            andre
            wrote on last edited by
            #5

            Again: why is that relevant? Why do you care in what order the results are returned?

            1 Reply Last reply
            0
            • ? Offline
              ? Offline
              A Former User
              wrote on last edited by
              #6

              Actually I need to load it in insertion order.

              Thanks.

              1 Reply Last reply
              0
              • M Offline
                M Offline
                mlong
                wrote on last edited by
                #7

                See my post above.

                Software Engineer
                My views and opinions do not necessarily reflect those of anyone -- living or dead, real or fictional -- in this universe or any other similar multiverse node. Void where prohibited. Your mileage may vary. Caveat emptor.

                1 Reply Last reply
                0
                • A Offline
                  A Offline
                  andre
                  wrote on last edited by
                  #8

                  In that case, QHash is not your class to use. Nor is QMap. Use a something like this:
                  @
                  typedef QPair<int, QString> intStringPair;
                  QVector<intStringPair> vector(3);
                  //do your inserts
                  @

                  You may replace the QPair with a struct, and the QVector with a QList if you prefer.

                  1 Reply Last reply
                  0
                  • ? Offline
                    ? Offline
                    A Former User
                    wrote on last edited by
                    #9

                    So what would be the solution to keep the insertion order and still enjoy the fast lookup of a hash?

                    1 Reply Last reply
                    0
                    • M Offline
                      M Offline
                      mlong
                      wrote on last edited by
                      #10

                      I suggested above, keeping a QList (or QVector) of the keys for iteration purposes, and using the QHash to store the values.

                      Software Engineer
                      My views and opinions do not necessarily reflect those of anyone -- living or dead, real or fictional -- in this universe or any other similar multiverse node. Void where prohibited. Your mileage may vary. Caveat emptor.

                      1 Reply Last reply
                      0
                      • ? Offline
                        ? Offline
                        A Former User
                        wrote on last edited by
                        #11

                        Certainly not as elegant as a single container. Perhaps such a container would make a good addition to Qt?

                        1 Reply Last reply
                        0
                        • M Offline
                          M Offline
                          mlong
                          wrote on last edited by
                          #12

                          It's not something that I've needed to do very often. And in the instances it has been, it's been simple enough to write a wrapper class that combines the functionality of the the two. But YMMV.

                          Software Engineer
                          My views and opinions do not necessarily reflect those of anyone -- living or dead, real or fictional -- in this universe or any other similar multiverse node. Void where prohibited. Your mileage may vary. Caveat emptor.

                          1 Reply Last reply
                          0
                          • A Offline
                            A Offline
                            andre
                            wrote on last edited by
                            #13

                            QMap is usually a good enough replacement, but when needed, I have also used a list of structures in combination with a QHash. I usually just stored either the list index in the hash, or alternatively a pointer to the struct in the list. Also: you should consider how big your list really is, and if it even makes sense to use a QHash. You say you need QHash, but remember that QHash is not always faster than QMap or even iterating over a QVector.

                            1 Reply Last reply
                            0
                            • ? Offline
                              ? Offline
                              A Former User
                              wrote on last edited by
                              #14

                              Obviously such a data structure would make sense in large collections where order is important just as fast lookup. In such scenario even a single extra pointer could end up costing plenty of memory. And then there is the indirection performance penalty.

                              1 Reply Last reply
                              0
                              • A Offline
                                A Offline
                                andre
                                wrote on last edited by
                                #15

                                Basically, what you are looking for is a hash with multiple keys. There are such classes available, but not in Qt. That does not mean you can't use them. For instance, take a look at "Boost.MultiIndex":http://www.boost.org/doc/libs/1_41_0/libs/multi_index/doc/tutorial/index.html

                                Note that the additional storage and indirection penalties will always be there. Either they are inside the container, or external, but you are going to need additional data for bookkeeping if you want to access the data in more than one way.

                                1 Reply Last reply
                                0
                                • ? Offline
                                  ? Offline
                                  A Former User
                                  wrote on last edited by
                                  #16

                                  I'm not been able to create QHash<int,QVariant> var.

                                  Is that impossible?

                                  Why?

                                  When I try that I see the errors below:

                                  In file included from c:\QtSDK\Desktop\Qt\4.8.1\mingw\include\QtCore/QHash:1,
                                  from ....\complementos/matriz.h:5,
                                  from ....\complementos\matriz.cpp:1:
                                  c:\QtSDK\Desktop\Qt\4.8.1\mingw\include\QtCore/qhash.h: In instantiation of 'QHashNode<int, QVariant>':
                                  c:\QtSDK\Desktop\Qt\4.8.1\mingw\include\QtCore/qhash.h:521: instantiated from 'static void QHash<Key, T>::deleteNode2(QHashData::Node*) [with Key = int, T = QVariant]'
                                  c:\QtSDK\Desktop\Qt\4.8.1\mingw\include\QtCore/qhash.h:570: instantiated from 'void QHash<Key, T>::freeData(QHashData*) [with Key = int, T = QVariant]'
                                  c:\QtSDK\Desktop\Qt\4.8.1\mingw\include\QtCore/qhash.h:283: instantiated from 'QHash<Key, T>::~QHash() [with Key = int, T = QVariant]'
                                  ....\complementos\matriz.cpp:4: instantiated from here
                                  c:\QtSDK\Desktop\Qt\4.8.1\mingw\include\QtCore/qhash.h:253: error: 'QHashNode<int, T>::value' has incomplete type
                                  c:\QtSDK\Desktop\Qt\4.8.1\mingw\include\QtCore/qobject.h:66: error: forward declaration of 'struct QVariant'
                                  mingw32-make.exe[1]: *** [debug/matriz.o] Error 1
                                  mingw32-make.exe: *** [debug] Error 2
                                  10:55:23: The process "C:\QtSDK\mingw\bin\mingw32-make.exe" exited with code 2.
                                  Error while building project cliente (target: Desktop)
                                  When executing build step 'Make'

                                  1 Reply Last reply
                                  0
                                  • A Offline
                                    A Offline
                                    andre
                                    wrote on last edited by
                                    #17

                                    You probably didn't #include <QVariant>

                                    1 Reply Last reply
                                    0
                                    • ? Offline
                                      ? Offline
                                      A Former User
                                      wrote on last edited by
                                      #18

                                      Ok!

                                      It works!

                                      1 Reply Last reply
                                      0
                                      • A Offline
                                        A Offline
                                        andre
                                        wrote on last edited by
                                        #19

                                        <schoolmaster mode>
                                        Do you understand how I arrived at that conclusion?

                                        1 Reply Last reply
                                        0
                                        • ? Offline
                                          ? Offline
                                          A Former User
                                          wrote on last edited by
                                          #20

                                          No.

                                          I would appreciate if you explain.

                                          1 Reply Last reply
                                          0

                                          • Login

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • Users
                                          • Groups
                                          • Search
                                          • Get Qt Extensions
                                          • Unsolved