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. [SOLVED]Behaviour of QMultiMap
Forum Update on Monday, May 27th 2025

[SOLVED]Behaviour of QMultiMap

Scheduled Pinned Locked Moved General and Desktop
13 Posts 3 Posters 8.7k Views
  • 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.
  • K Offline
    K Offline
    KA51O
    wrote on 26 Jul 2011, 09:16 last edited by
    #1

    Hi everyone,

    I was always under the impression that QMultiMap would behave like this:

    If i insert 3 ValuePairs {(1,one),(2,two),(2,zwei)} the QMultiMap would look like this
    @
    1 | 2
    one | two
    | zwei
    @
    but now during debugging I get the feeling it does this
    @
    1 | 2 | 2
    one | two | zwei
    | zwei | two
    @
    I iterate over the map like this

    @QList<int> result;

    QMultiMap<QString, int>::const_iterator it = sortedMultiMap.constBegin();
    while(it != sortedMultiMap.constEnd())
    {
    QList<int> values = sortedMultiMap.values(it.key());
    for(int i = 0; i < values.size(); ++i)
    {
    result.append(values.at(i);
    }
    ++it;
    }@

    Can anyone plz provide some insight. I'm just using the QMultiMap to sort some pointers to objects with regard to their timestamp. At some point I want to put them in a QList with the oldest timestamp (the smallest timestamp) first.

    1 Reply Last reply
    0
    • K Offline
      K Offline
      koahnig
      wrote on 26 Jul 2011, 09:32 last edited by
      #2

      Well, QMultiMap does only sorting the "key" (your '1', '2') not the value. It supposed to do it this way. It is the same stl multimap.
      You need to define it differently for what you are looking for.

      Vote the answer(s) that helped you to solve your issue(s)

      1 Reply Last reply
      0
      • A Offline
        A Offline
        andre
        wrote on 26 Jul 2011, 09:38 last edited by
        #3

        The iterator you use iterates over all key/value pairs you inserted into the map. If you inserted a key twice, then you get an iterator with that key twice. Then, inside your loop, you request all values for a specific key again. That means that you will find the same values more than one time in your case. The order in which these values are returned is not defined.

        If you want all values if your map, you should just use QMap::values(). If you want to iterate over all key/value pairs, then use both the key() and the value() method of the iterator to get to your items.

        1 Reply Last reply
        0
        • K Offline
          K Offline
          KA51O
          wrote on 26 Jul 2011, 09:54 last edited by
          #4

          Thanks for your quick responses.

          I think my problem is that my QMultiMap can not sort the keys correctly if they're of the type QDateTime.
          Although QDateTime provides the neccessary < operator.
          If I just iterate like this
          @
          QList<somePointer*> result;

          QMultiMap<QDateTime, somePointer*>::const_iterator it = sortedMultiMap.constBegin();
          while(it != sortedMultiMap.constEnd())
          {
          result.append(it.value());
          ++it;
          }
          @
          I only get three values which is what I want but they are inserted in the wrong order.
          In my app I get this for example: (05:59 | somePointer1) ; (06:44 | somePointer2) ; (06:00 | somePointer3) in that exact order (which is the order they were inserted in the QMultiMap); when I really want this: (05:59 | somePointer1); (06:00 | somePointer3) ; (06:44 | somePointer2) .

          So how can I iterate over my keys in the correct order and not get values twice or more?

          I already checked my QList before inserting but the problem regarding the order still remains
          @
          QList<somePointer*> result;

          QMultiMap<QDateTime, somePointer*>::const_iterator it = sortedMultiMap.constBegin();
          while(it != sortedMultiMap.constEnd())
          {
          QList<somePointer*> values = sortedMultiMap.values(it.key());
          for(int i = 0; i < values.size(); ++i)
          {
          if(!result.contains(values.at(i)))
          {
          result.append(values.at(i));
          }
          }
          ++it;
          }
          @

          1 Reply Last reply
          0
          • A Offline
            A Offline
            andre
            wrote on 26 Jul 2011, 10:18 last edited by
            #5

            Weird, I thought QMap would keep it sorted property. Just to be sure, those QDateTimes do have the same date, right?

            If QDateTimes are not properly sorted, then that would qualify as a bug. As a workaround in that case, you could:

            first retreive the used keys using the keys() method, then

            sort the list of keys (qSort should do), then

            iterate over the list of keys, and

            for each key, retreive the list of values (which will not be sorted, of course)

            But if you really need such a workaround, be sure to file a bug report agains QMap in "Jira":http://bugreports.qt.nokia.com as well!

            1 Reply Last reply
            0
            • K Offline
              K Offline
              KA51O
              wrote on 26 Jul 2011, 10:22 last edited by
              #6

              I could of course just use stl::list insert all keys then sort the list and iterate over the MultiMap using the sorted keys, but thats kind of inefficient isn't it ^^.

              1 Reply Last reply
              0
              • K Offline
                K Offline
                KA51O
                wrote on 26 Jul 2011, 10:25 last edited by
                #7

                HiHi

                had the same idea :-P

                @Andre: Yes they're all of the same date only the time varries. And even if they had different dates shouldn't that be handled correctly by QDateTime's < operator ?

                1 Reply Last reply
                0
                • A Offline
                  A Offline
                  andre
                  wrote on 26 Jul 2011, 10:25 last edited by
                  #8

                  [quote author="KA51O" date="1311675772"]I could of course just use stl::list insert all keys then sort the list and iterate over the MultiMap using the sorted keys, but thats kind of inefficient isn't it ^^.[/quote]
                  Sure it is inefficient, that's why I called it a workaround and qualified the situation as bug if it were truly needed.

                  1 Reply Last reply
                  0
                  • K Offline
                    K Offline
                    KA51O
                    wrote on 26 Jul 2011, 10:29 last edited by
                    #9

                    @Andre I wrote that before you posted the exact same idea. I didn't mean to criticise your answer.

                    1 Reply Last reply
                    0
                    • A Offline
                      A Offline
                      andre
                      wrote on 26 Jul 2011, 10:47 last edited by
                      #10

                      No, that' s ok. If the dates are all the same, and the times are then sorted like you showed, then there is a bug. The point was, that if the dates would have been different, the sorting you showed us (only showing the times) could have been correct. Of course the sorting should be correct even if the dates are different.

                      Please prepare a small, self-contained example that displays the faulty behaviour, and attach that to your bug report.

                      1 Reply Last reply
                      0
                      • K Offline
                        K Offline
                        KA51O
                        wrote on 26 Jul 2011, 10:52 last edited by
                        #11

                        Ok I wrote a small test case and in that test case the behaviour is correct (code below)

                        @
                        QMultiMap<QDateTime,int> timeSortedIntegers;
                        timeSortedIntegers.insert(QDateTime::currentDateTime().addSecs(-120),1);
                        timeSortedIntegers.insert(QDateTime::currentDateTime(),2);
                        timeSortedIntegers.insert(QDateTime::currentDateTime().addSecs(-60),3);

                        QList<int> testList1;
                        QMultiMap<QDateTime,int>::const_iterator it1 = timeSortedIntegers.constBegin();
                        while(it1 != timeSortedIntegers.constEnd())
                        {
                        testList1.append(it1.value());
                        ++it1;
                        }

                        QList<int> testList2;
                        QMultiMap<QDateTime,int>::const_iterator it2 = timeSortedIntegers.constBegin();
                        while(it2 != timeSortedIntegers.constEnd())
                        {
                        QList<int> values = timeSortedIntegers.values(it2.key());
                        for(int i = 0; i < values.size(); ++i)
                        {
                        if(!testList2.contains(values.at(i)))
                        {
                        testList2.append(it2.value());
                        }
                        }
                        ++it2;
                        }

                        for(int j = 0; j < testList1.size(); ++j)
                        {
                        int testInt1 = testList1.at(j);
                        int test1 = testInt1;
                        }

                        for(int k = 0; k < testList1.size(); ++k)
                        {
                        int testInt2 = testList2.at(k);
                        int test2 = testInt2;
                        }
                        @

                        So I must be doing something stupid in my code.

                        I'll keep you posted.

                        1 Reply Last reply
                        0
                        • K Offline
                          K Offline
                          KA51O
                          wrote on 26 Jul 2011, 12:55 last edited by
                          #12

                          I got it.

                          One of the QDateTime's I used was in UTC format and all the others in localTime format.
                          The result was actually correct if all QDateTime's were converted to the same type.

                          Curses!!!!

                          1 Reply Last reply
                          0
                          • A Offline
                            A Offline
                            andre
                            wrote on 26 Jul 2011, 13:08 last edited by
                            #13

                            Ah! Great that you managed to solve it. It seemed an unlikely bug to be in QMap or QDateTime (something that would have been caught by a unit test), but you never know... Qt is not perfect. But, in this case, it was pilot error after all :-) An easy mistake to make, and a hard to spot one. I am glad you managed to fix it!

                            1 Reply Last reply
                            0

                            1/13

                            26 Jul 2011, 09:16

                            • Login

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