Link to home
Start Free TrialLog in
Avatar of EM77
EM77

asked on

Sort a vector of objects

Hi!

I have several pointers to objects in a vector to be sorted. I think I can use sort(myVector.begin(),myVector.end()) but this method sort by pointer memory directions.

I have an object called Vehicle with an int price. So I'd like to sort the vehicles by price.

Is there any method to use sort and tell it to sort by the objects instead of sorting by the pointers of the vectors ?

Many Thanks!

Enric
Avatar of jkr
jkr
Flag of Germany image

>>I have an object called Vehicle with an int price. So I'd like to sort the vehicles by price.

All you need to do is to provide an predicate object that takes care of the comparison, e.g.

class Vehicle {

public:

int GetPrice () const { return price;}

private;

int price;
};

struct greater_VehiclePtr : public greater<Vehicle*> {
public:
  bool operator()(Vehicle* pl, Vehicle* pr) { return pl->GetPrice() > pr->GetPrice(); }
};

vector<Vehicle*> vVehicles;

//...

sort(vVehicles.begin(), vVehicles.end(), greater_VehiclePtr());
Avatar of EM77
EM77

ASKER

Where do you define the greater_VehiclePtr? Inside the Vehicle hearder??¿?¿?
That would be one possible place. As a rule of thumb: Define it where you need it. The following demostrates the whole thing:

#include <vector>
#include <algorithm>
#include <functional>
using namespace std;

class Vehicle {

public:

int GetPrice () const { return price;}

private:

int price;
};

struct greater_VehiclePtr : public greater<Vehicle*> {
public:
  bool operator()(Vehicle* pl, Vehicle* pr) { return pl->GetPrice() > pr->GetPrice(); }
};

int main () {

vector<Vehicle*> vVehicles;

//...

sort(vVehicles.begin(), vVehicles.end(), greater_VehiclePtr());

return 0;
}
Avatar of EM77

ASKER

Ok, It works!!!!

Now I have another problem. First of all I have to list the objects sorted by price, then I have to list it as they were created.

When I wrote sort(......) my vVector is modified so then I'd like to set it as it was created...

Any idea???

Many Thanks!

Enric
>>I have to list it as they were created.

What do you mean?
That works at my system (VC6/XP):

class A
{
public:
    string a;
    A(const char* s) : a(s) {};

};


bool Aless(const A*& pa1, const A*& pa2)
{
    return pa1->a < pa2->a;
}

class A
{
public:
    string a;
    A(const char* s) : a(s) {};

    static bool less(const A*& pa1, const A*& pa2)
    {
        return pa1->a < pa2->a;
    }
};

int main()
{
    vector<A*> arr;
    A a1("John");
    A a2("James");
    A a3("Bill");
    arr.push_back(&a1);
    arr.push_back(&a2);
    arr.push_back(&a3);
    sort(arr.begin(), arr.end(), A::less);

    for (int ii = 0; ii < arr.size(); ++ii)
        cout << arr[ii]->a << endl;

    return 0;
};

It passes a substitute to the built-in operator< function that could be defined for class types only.

Regards, Alex
That part needs to removed:

class A
{
public:
    string a;
    A(const char* s) : a(s) {};

};


bool Aless(const A*& pa1, const A*& pa2)
{
    return pa1->a < pa2->a;
}

>>>>  I'd like to set it as it was created...

You need to add a member that counts :

class Vehicle
{
    static int lastCounter;
    int counter;
    int price;
public:
    Vehicle(int pr) : counter(++lastCounter), price(pr) {}
    ...
};


// vehicle.cpp

#include "vehicle.h"

// initialize counter
int Vehicle::lastCounter = 0;


With that you could define a further sort function that goes for counter rather than for price.

Regards, Alex
Avatar of EM77

ASKER

First of all I'm adding pointer to vector as I show:

vVehicles.push_back(pVehicle1); //pVehicle->price = 1000
vVehicles.push_back(pVehicle2); //pVehicle->price = 3000
vVehicles.push_back(pVehicle3); //pVehicle->price = 2000

1.-Now I use your code and I list all vehicles in vector so they're showed sorted

pVehicle2
pVehicle3
pVehicle1

2.- Now I need to show all vehicles (without using your sort method) as I pushed_back in vector, so I need to show  as I've created the object.
The result need to be:

pVehicle1
pVehicle2
pVehicle3

But I'm showing it from the first place of the vector to the end and the result is the same as sorted vehicles. I understand that when we sort vehicles we are modifying the vector so when I'm trying to show as I've created the vehicles it is shown incorrect.

Sorry but my english is not as good as I'd like ! ;)

Thanks
ASKER CERTIFIED SOLUTION
Avatar of itsmeandnobodyelse
itsmeandnobodyelse
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
>>>> int Vehicle::lastCounter = 0;

I forgot to initialize the static member.

Regards, Alex
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial