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. Unsorted QVector
Forum Update on Monday, May 27th 2025

Unsorted QVector

Scheduled Pinned Locked Moved Solved General and Desktop
qvectorsorting
11 Posts 7 Posters 3.5k 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.
  • BuckwheatB Offline
    BuckwheatB Offline
    Buckwheat
    wrote on last edited by
    #2

    Hi @sayan275

    Unfortunately because of the standard string compare functions you get the behavior you are seeing. The easiest way to solve this in an ideal sense is to prepend '0' to all the numbers. This is not practical or desirable. Instead, what you will need to do is write your own smart compare function that has some knowledge of your file names.

    Luckily, QVector, QList, and QMap can be used like the C++Library std::vector, std::list, and std::map.

    Here is what I am referring to:

    int my_comparator (const QString& lhs, const QString& rhs)
    {
    // Write some smart stuff to compare the files with numeric ordering
    if (lhs < rhs) return -1;
    else if (lhs > rhs) return 1;
    else return 0;
    }

    ... more code here ...

    std::sort (my_vector.begin (), my_vector.end (), my_comparator);

    Unfortunately, there is no easy way to do this except your custom function. Luckily everything you need is available. I would suggest you look online for a good test comparator that does what you want. Here is a decent article you can read about human sorting.

    https://blog.codinghorror.com/sorting-for-humans-natural-sort-order/

    Dave Fileccia

    1 Reply Last reply
    4
    • Gojir4G Offline
      Gojir4G Offline
      Gojir4
      wrote on last edited by Gojir4
      #3

      Hello,

      This is because you are sorting strings, so 10, 100, etc.. comes before 2 in alphabet order.
      You have to convert them to numbers to sort them correctly.

      You can use std::sort() with custom "Compare" method for that.

      using lambda :

      std::sort(vector.begin(), vector.end(), [](const QString& a, const QString b) { 
          bool okA, okB;
          int ia = QFileInfo(a).baseName().toUint(&okA);
          int ib = QFileInfo(a).baseName().toUint(&okB);
         if(!okA || !okB)
              return a < b;
          return ia < ib; 
      });
      

      without lambda:

      bool compareNumberFileName(const QString& a, const QString b) { 
          bool okA, okB;
          int ia = QFileInfo(a).baseName().toUint(&okA);
          int ib = QFileInfo(a).baseName().toUint(&okB);
         if(!okA || !okB)
              return a < b;
          return ia < ib; 
      }
      
      std::sort(vector.begin(), vector.end(), compareNumberFileName);
      

      In case you are using always the same folder, you can store only numbers corresponding to file names in QVector<uint> and then construct the file name when it's necessary.

      S 1 Reply Last reply
      5
      • mrjjM Offline
        mrjjM Offline
        mrjj
        Lifetime Qt Champion
        wrote on last edited by
        #4

        Hi
        I was wondering if QStringList would just work if the goal is to just have them in the same order as inserted ?

        Gojir4G S 2 Replies Last reply
        4
        • mrjjM mrjj

          Hi
          I was wondering if QStringList would just work if the goal is to just have them in the same order as inserted ?

          Gojir4G Offline
          Gojir4G Offline
          Gojir4
          wrote on last edited by
          #5

          @mrjj Yes it should. QList<> keep items in the order they are inserted. This is also the case of QVector<>.

          1 Reply Last reply
          3
          • mrjjM mrjj

            Hi
            I was wondering if QStringList would just work if the goal is to just have them in the same order as inserted ?

            S Offline
            S Offline
            sayan275
            wrote on last edited by
            #6

            @mrjj It's the same with QStringList. Actually the problem is with the container only which contains the qstring paths as sorted,
            "./zThumbnail/1004.jpeg"
            "./zThumbnail/1005.jpeg"
            "./zThumbnail/1006.jpeg"
            "./zThumbnail/1007.jpeg"
            "./zThumbnail/1008.jpeg"
            "./zThumbnail/1009.jpeg"
            "./zThumbnail/101.jpeg"
            "./zThumbnail/1010.jpeg"
            "./zThumbnail/1011.jpeg"
            "./zThumbnail/1012.jpeg"
            "./zThumbnail/1013.jpeg"

            QFileInfoList filelistinfo = dir.entryInfoList();
            foreach (const QFileInfo &fileinfo, filelistinfo) {
            imagePath.push_back(fileinfo.absoluteFilePath());
            qDebug() << fileinfo.absoluteFilePath();
            }

            aha_1980A 1 Reply Last reply
            0
            • Gojir4G Gojir4

              Hello,

              This is because you are sorting strings, so 10, 100, etc.. comes before 2 in alphabet order.
              You have to convert them to numbers to sort them correctly.

              You can use std::sort() with custom "Compare" method for that.

              using lambda :

              std::sort(vector.begin(), vector.end(), [](const QString& a, const QString b) { 
                  bool okA, okB;
                  int ia = QFileInfo(a).baseName().toUint(&okA);
                  int ib = QFileInfo(a).baseName().toUint(&okB);
                 if(!okA || !okB)
                      return a < b;
                  return ia < ib; 
              });
              

              without lambda:

              bool compareNumberFileName(const QString& a, const QString b) { 
                  bool okA, okB;
                  int ia = QFileInfo(a).baseName().toUint(&okA);
                  int ib = QFileInfo(a).baseName().toUint(&okB);
                 if(!okA || !okB)
                      return a < b;
                  return ia < ib; 
              }
              
              std::sort(vector.begin(), vector.end(), compareNumberFileName);
              

              In case you are using always the same folder, you can store only numbers corresponding to file names in QVector<uint> and then construct the file name when it's necessary.

              S Offline
              S Offline
              sayan275
              wrote on last edited by
              #7

              @Gojir4 Thanks for the suggestion.
              I constructed the filepaths.

              D 1 Reply Last reply
              0
              • S sayan275

                @mrjj It's the same with QStringList. Actually the problem is with the container only which contains the qstring paths as sorted,
                "./zThumbnail/1004.jpeg"
                "./zThumbnail/1005.jpeg"
                "./zThumbnail/1006.jpeg"
                "./zThumbnail/1007.jpeg"
                "./zThumbnail/1008.jpeg"
                "./zThumbnail/1009.jpeg"
                "./zThumbnail/101.jpeg"
                "./zThumbnail/1010.jpeg"
                "./zThumbnail/1011.jpeg"
                "./zThumbnail/1012.jpeg"
                "./zThumbnail/1013.jpeg"

                QFileInfoList filelistinfo = dir.entryInfoList();
                foreach (const QFileInfo &fileinfo, filelistinfo) {
                imagePath.push_back(fileinfo.absoluteFilePath());
                qDebug() << fileinfo.absoluteFilePath();
                }

                aha_1980A Offline
                aha_1980A Offline
                aha_1980
                Lifetime Qt Champion
                wrote on last edited by
                #8

                @sayan275 neither QVector nor QStringList are sorted!

                they are just containers that can be sorted. but if you append or push_back, than new items appear at the end.

                so you will have to sort the list yourself, as already suggested.

                Qt has to stay free or it will die.

                1 Reply Last reply
                4
                • S sayan275

                  @Gojir4 Thanks for the suggestion.
                  I constructed the filepaths.

                  D Offline
                  D Offline
                  Devopia53
                  wrote on last edited by Devopia53
                  #9

                  @sayan275

                  With QMap, the items are always sorted by key.

                  You can also use the QMap. like this:

                  QFileInfoList filelistinfo = dir.entryInfoList(QStringList() << "*.jpeg");
                  QMap<int, QString> map;
                  for (const QFileInfo &fileinfo : qAsConst(filelistinfo))
                      map[fileinfo.baseName().toInt()] = fileinfo.absoluteFilePath();
                  for (QString value : qAsConst(map))
                      qDebug() << value;
                  
                  1 Reply Last reply
                  2
                  • J.HilkJ Online
                    J.HilkJ Online
                    J.Hilk
                    Moderators
                    wrote on last edited by
                    #10

                    To add my 2 cents,
                    you could sort twice, first along the string length than, in blocks, along the string itself.


                    Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                    Q: What's that?
                    A: It's blue light.
                    Q: What does it do?
                    A: It turns blue.

                    1 Reply Last reply
                    0
                    • S Offline
                      S Offline
                      sayan275
                      wrote on last edited by
                      #11

                      I got it done by the below code

                      QFileInfoList filelistinfo = dir.entryInfoList();
                      for(const QFileInfo &fileinfo: filelistinfo) 
                          imagePath.push_back(fileinfo.absoluteFilePath());
                      
                      std::sort(imagePath.begin(), imagePath.end(),
                                [](const QString & a, const QString & b) -> bool
                      {
                          return QFileInfo(a).baseName().toInt() < QFileInfo(b).baseName().toInt();
                      });
                      
                      qDebug()<<imagePath;
                      
                      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