Sorting a list

S

SKumar

Hi All,
I have a list which contains my class objects. My class is
having two variables. I want to sort the list based on these two
variables.

Ex :
class Foo
{
...
...
public:
int nAngle;
int nDist;
};

int main()
{
std::vector<Foo> list;
...
...
//here i want to sort the list...first based on nAngle & then
nDist...
}

PS: Though in this case my variables are int, it may be anything else.
Is there any simple & generic way to do this?

Thanks,
#SKumar#
 
M

Michiel.Salters

SKumar said:
Hi All,
I have a list which contains my class objects. My class is
having two variables. I want to sort the list based on these two
variables.

Ex :
class Foo
{
public:
int nAngle;
int nDist;
};
std::vector<Foo> list;

That's not a list. A std::list<Foo> would be a list, but they don't
sort well.

Anyway, you need std::sort. If you tell it how to compare two Foo's, it

can sort a vector<Foo>. It can also sort a std::deque<Foo>, because
that
also has random iterators, but not std::list.
 
P

persenaama

Write a predicate compare function and use the std::vector:.sort that
invokes it.

int compare_pred(const Foo& a, const Foo& b)
{
// TODO: implement a < b here
}

// invoke like this
list.sort(compare_pred);
 
D

Daniel T.

"SKumar said:
Hi All,
I have a list which contains my class objects. My class is
having two variables. I want to sort the list based on these two
variables.

Ex :
class Foo
{
...
...
public:
int nAngle;
int nDist;
};

int main()
{
std::vector<Foo> list;
...
...
//here i want to sort the list...first based on nAngle & then
nDist...
}

PS: Though in this case my variables are int, it may be anything else.
Is there any simple & generic way to do this?

Yes, you have to make an op< for comparing two Foos...

bool operator<( const Foo& lhs, const Foo& rhs ) {
//if ( lhs is "smaller" than rhs ) return true;
//else return false;
}

Once you have the above, you can:

sort( list.begin(), list.end() );

BTW, "list" probably isn't the best name for a vector of Foo's.
 
D

Dietmar Kuehl

SKumar said:
I have a list which contains my class objects. My class is
having two variables. I want to sort the list based on these two
variables.

The first thing to do when you want to sort objects is to define
a [strict partial] ordering on them. For the case of your two
variables you probably could do with a lexicographical order as
you could obtain using tuples (either from TR1 or from Boost):

return tie(obj1.nAngle, obj1.nDist) < tie(obj2.nAngle, obj2.nDist);

'tie()' is a factory function creating a tuple of references and
the expression just returns the result of comparing the two created
tuples. The same effect can be obtained using appropriate logic to
compare the involved object but I consider the above much more
readable than manual alternative.

Once you have your ordering defined, you would next have to determine
how to apply the order. There are generally two possible approaches:

1. If the ordering always applies reasonably to the involved objects,
you can make the object available by overloading suitable
operators for the corresponding class. Effectively, this means
that you define 'operator<()' for objects for your class:

bool operator< (Type const& obj1, Type const& obj2) {
// e.g. the tuple expression goes here if the operator has
// appropriate access to the member variables
}

2. If the ordering is specific to the task at hand and is not really
related to the objects in general, you would rather use a
"predicate" which is just an object that can be used with the
function call operator on the involved objects. Such a predicate
can be a simple function (in which case the object is actually
just the function pointer) or a class, e.g.:

struct MyCompare {
bool operator()(Type const& obj1, Type const& obj2) const {
// comparing the objects goes here
}
};

With this in place, you could easily sort a random access sequence
of your objects using either the default predicate which happens to
be 'std::less<Type>' and simply uses 'operator<()', i.e.

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

or you can use the 'std::sort()' function specifying the predicate:

std::sort(sequence.begin(), sequence.end(), MyCompare());

If you really want to sort a 'std::list<Type>', you would use the
member 'sort()' because 'std::list<Type>' does not provide random
access iterators but can still be sorted efficiently.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top