Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sorting A Vector Of Structs According To Contained Data

I am sorry if there is similar questions already present on the website, but am currently failing to understand certain parts of the algorithm.

I have a Struct that contains information on user account information for my game:

struct Account
{
    int Position;
    string Name;
    int Score;
    string Date;
    int Level;

    bool operator < (User SOMETHING, User SOMETHING)
    {
         return (SOMETHING < SOMETHING);
    }
};

vector<Account> User;
User.push_back(Account());
User.push_back(Account());
User.push_back(Account());

User[0].Position=1;
User[1].Position=2;
User[2].Position=3;

sort(User.begin(), User.end(), Account);

I need each struct of my vector to be to be organized, say for instance, in descending/ascending order for the "Position" value that each contains.

I just need help on (1) bool operator function (e.g. parameters and return values), and (2) How do I have it so that I can sort it by multiple variables like the positions, scores & level. (Would I need to have 3 bool operator functions?)

like image 441
Donald Avatar asked Sep 28 '22 12:09

Donald


1 Answers

Use std::tie, something like this:

struct Account
{
    int Position;
    string Name;
    int Score;
    string Date;
    int Level;
};

bool operator < (const Account& lhs, const Account& rhs)
{
    return std::tie(lhs.Name,lhs.Score,lhs.Date) < std::tie(rhs.Name,rhs.Score,rhs.Date);
}

will sort according to Name first, if Name is equal then according to Score, when both Name and Score are equal then according to Date.

Sorting is simply done by:

std::sort(User.begin(), User.end());

Which, by default, uses operator< on the contained objects of type Account.


Update: I misunderstood your question. In your case you need separated comparators, e.g.

struct by_name_ascending
{
    bool operator()(const Account& lhs, const Account& rhs) const
    {
        return lhs.Name < rhs.Name;
    }
};

struct by_score_descending
{
    bool operator()(const Account& lhs, const Account& rhs) const
    {
        return lhs.Score > rhs.Score;
    }
};

and sort the vector with

std::sort(User.begin(), User.end(), by_name_ascending());

With lambdas, you could also use

std::sort(User.begin(), User.end(),
  [](const Account& lhs, const Account& rhs){
    return lhs.Name < rhs.Name;
  }
);

directly, simply switching < and > for ascending/descending. No need for other helpers or operators in the class/struct itself.

like image 188
Daniel Frey Avatar answered Sep 30 '22 09:09

Daniel Frey