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.
  • S Offline
    S Offline
    sayan275
    wrote on last edited by sayan275
    #1

    Hi,

    I have a QVector<QString>, which should store filepaths, like
    ./abc/1.jpg
    ./abc/2.jpg
    ./abc/3.jpg
    .
    .
    .
    ./abc/1209.jpg

    But instead of storing it in the above order, it's storing like
    ./abc/1.jpg
    ./abc/10.jpg
    ./abc/100.jpg
    ./abc/1000.jpg
    ./abc/1001.jpg
    .
    .

    How can I store the image filepath in numeric sequence?

    1 Reply Last reply
    0
    • 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 Offline
                      J.HilkJ Offline
                      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