Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QT std::sort function is not sorting correctly



  • I have below structure.

    struct test
    {
    uint id;
    QString name;
    };

    I have below map which I am inserting element.
    map<uint, test> maptest1;
    maptest1.insert ( 1, {1,"Ram"));
    maptest2.insert( 2, { 1,"Shyam"));
    maptest3.insert(3, {2,"Mohan"));

    Now I am trying to sort this map based on ID of test struct.

    I did below copied all things in vector

    vector<test> test1;
    for(const test& a : maptest.values())
    {
    test1.push_back(a);
    }

    Now I am sorting the vector using below function
    std::sort(test1.begin() , test2.begin(), [this]( const test& test1 , const test& test2 ) { return test1.id < test2.id});

    But sorting does not works fine for those who have same id in test (like ram and shyam).

    I am working with some more large numbers of such instances this is just as an example.

    Can anyone help me


  • Moderators

    hi, @Ayush-Gupta

    why don't you modify your test lambda then?

    std::sort(test1.begin() , test2.begin(), [this]( const test& test1 , const test& test2 )->bool { 
        if(test1.id == test2.id) {
            //case same ID -> your other compare method
            return other;
        }
        return test1.id < test2.id
    });
    


  • @J-Hilk I did like this but not works
    std::sort(test1.begin() , test2.begin(), [this]( const test& test1 , const test& test2 )->bool {
    if(test1.id == test2.id) {
    return false;
    }
    return test1.id < test2.id
    });



    • what you want is probably just to use std::stable_sort instead.
    • test1.begin() , test2.begin() What is this? Normally it's test1.begin() , test1.end()
    • for(const test& a : maptest.values()) test1.push_back(a); As far as I remember std::map diesn't have a values() method. whatever you are using, the values method propably already returns a sortable unidimensional container of the values, there is no need to copy them over to a 3rd container


  • @VRonin That is typo I am using
    test1.begin() , test2.end().
    Why you think std::stable_sort will work instead of sort?


  • Lifetime Qt Champion

    @Ayush-Gupta said in QT std::sort function is not sorting correctly:

    test1.begin() , test2.end()

    Which is wrong too. Both most be from the same data structure.

    Regards



  • @Ayush-Gupta said in QT std::sort function is not sorting correctly:

    Why you think std::stable_sort will work instead of sort?

    The only difference between sort and stable_sort is how they handle items with the same value. stable_sort keeps them in the same relative order as the original vector


  • Moderators

    actually, didn't see the error @VRonin mentioned, with that fixed, it works

    for example:

    QVector<test> maptest1;
        maptest1.append( {1,"Ram"});
        maptest1.append( { 1,"Shyam"});
        maptest1.append( {2,"Mohan"});
    
        std::sort(maptest1.begin() , maptest1.end(), [=]( const test& test1 , const test& test2 )->bool {
            if(test1.id == test2.id) {
                //case same ID -> your other compare method
                return test1.name.at(0) > test2.name.at(0);
            }
            return test1.id < test2.id;
        });
        for(test a: maptest1){
            qDebug() << a.id << a.name;
        }
    //output:
    // 1 "Shyam"
    //1 "Ram"
    //2 "Mohan"
    


  • @VRonin You are right stable_sort works perfect for me.
    All many thanks for your help.


  • Lifetime Qt Champion

    @Ayush-Gupta So please mark this topic as SOLVED now. Thanks!


Log in to reply