Reputation: 2700
I've had a look at the following question : Sorting a vector of objects by a property of the object
And it seems very relevant to my case. I have a small number of Player objects (6-10), and they all have information such as their name, and several relevant stats. I want to sort them in descending order by one particular stat.
Still very confused about what the
Help please!
EDIT: FULL UPDATED CODE BELOW
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
using namespace std;
class Player {
public:
Player(string name, int Dex, int Mod, int Lvl, int& diceRoll);
int calcInitiative(int& diceRoll);
int diceRoll;
friend ostream& operator<<(ostream& out, const Player& player) {
return out << player.mName << " " << player.mInitiative;
}
bool operator<(const Player& rhs) const {
if(mInitiative < rhs.mInitiative) return true;
if(mInitiative > rhs.mInitiative) return false;
if(mInitiative == rhs.mInitiative) return false;
}
int mDex, mMod, mLvl, mInitiative;
string mName;
};
Player::Player(string name, int Dex, int Mod, int Lvl, int& diceRoll)
: mName(name), mDex(Dex), mMod(Mod), mLvl(Lvl)
{}
int Player::calcInitiative(int& diceRoll) {
return (mLvl/2) + mDex + mMod + diceRoll;
}
int main() {
int rollD, rollS; // etc.
vector<Player> playerVec;
cout << "Derek rolled: ";
cin >> rollD;
cout << '\n' << "Scott rolled: ";
cin >> rollS;
// etc.
Player Derek("Derek", 2, 0, 6, rollD);
Player B("B", 2, 0, 9, rollB);
// etc...
Derek.mInitiative = Derek.calcInitiative(rollD);
Scott.mInitiative = Scott.calcInitiative(rollS);
//etc.
playerVec.push_back(Derek);
playerVec.push_back(Scott);
// etc.
cout << "The initative order is: " << '\n';
sort (playerVec.begin(), playerVec.end());
for(vector<Player>::iterator it = playerVec.begin(); it != playerVec.end(); ++it) {
cout << *it << endl;
}
system("pause");
return 0;
}
Upvotes: 1
Views: 210
Reputation: 1666
You almost have all the code written already.
In your Player class, add the following function:
bool operator<(const Player& rhs) const;
and make it return true if this
is less than the right-hand-side. Similar to your last code block.
Now run:
sort(myVec.begin(), myVec.end());
That will do an in-place sort.
Edit: Here's a fully compilable example to show how it all works together:
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
class Player
{
public:
Player(int stat1, int stat2) : m_stat1(stat1), m_stat2(stat2) {}
bool operator<(const Player& rhs) const {
if(m_stat1 < rhs.m_stat1) return true;
if(m_stat1 > rhs.m_stat1) return false;
return m_stat2 < rhs.m_stat2;
}
friend ostream& operator<<(ostream& out, const Player& player) {
return out << player.m_stat1 << ", " << player.m_stat2;
}
private:
int m_stat1, m_stat2;
};
int main()
{
vector<Player> aPlayers;
aPlayers.push_back(Player( 1, 2 ));
aPlayers.push_back(Player( 1, 1 ));
aPlayers.push_back(Player( 5, 0 ));
std::sort(aPlayers.begin(), aPlayers.end());
for(vector<Player>::iterator it = aPlayers.begin();
it != aPlayers.end(); ++it)
{
cout << *it << endl;
}
}
Outputs:
1, 1
1, 2
5, 0
I put operator<< in there since you mentioned it in your comment, but it really has nothing to do with sorting. std::sort() will work just fine without it.
Edit 2: With your new code, you mention that the compiler is giving you an error. That error is likely because it can't be certain that the code will return a value. If you add return false
to the end of operator<
, it will stop giving you an error. That would also make the third line in your operator<
redundant.
As far as the results being in reverse order, sort
sorts in ascending order by default. There's a couple really simple ways to resolve this. The most obvious is to rewrite operator<
to generate the ordering your would prefer. A more general option is to feed reverse iterators into std::sort instead of the default iterators:
std::sort(aPlayers.rbegin(), aPlayers.rend());
rbegin()
and rend()
are just like begin()
and end()
, except they go in reverse.
Upvotes: 2
Reputation: 6490
By calling std::sort on a vector with a provided predicate (in your case this is a functor) you are already swapping your players.
In your sample after calling sort on myVec you will have your vector of of Player, or what ever T is sorted by the property x in a descending order.
So I see no purpose of switching / swapping anything manually.
Upvotes: 2