Sorting a List of Classes

Today whilst writing my Highscores library, which I’m currently using for Sweepy Cleaner but intend to also use for future XNA games such as those I’ll make at 3 Thing Game, I discovered an awesome feature of lists in C#.

This List.Sort() method, documented here, allows you to sort a list of classes and, because it uses the recursive QuickSort algorithm, its really quick! By default the Sort() method can sort any primitive types, such as strings, ints, float and doubles, without any parameters, which is pretty good but doesn’t allow you to fully utilize the method. This is where the IComparer interface comes in.

An interface, for those who don’t know, is like a rulebook. It says “if you claim to be a comparer, you must include methods with these names, that return these types, otherwise I wont let you claim to be a comparer by stopping you from compiling”.

An example person interface might be like the following


interface Person
{
string returnName();
int returnAge();
void Eat(string foodType);
}

This basically says “To be a person you must have a method which returns a string called returnString, a method which returns an int called returnAge and a void method called Eat which accepts a string parameter”. If you miss one of those methods off from your class, which then claims to be a person or you have a returnAge method but it returns a double rather than an int or an eat method which doesn’t accept a string parameter your code won’t compile, so you can see that Interfaces are pretty useful for making sure your classes adhere to a certain rule set. 🙂

The IComparer interface comes in useful, it dictates to you how to make a class which tells the Sort() method how to sort your list of classes.

A class which implements the IComparer interface must have a public int Compare method which accepts two objects in its signature. So if we’re sorting people by age we might have an IComparer like the following.


public class PeopleComparer : IComparer
{
public int Compare(People person1, People person2)
{
int returnValue = 1;
if (person1 != null && person2 != null)
{
returnValue = person2.Age.CompareTo(person1.Age);
}
return returnValue;
}
}

As you can see, our PeopleComparer claims to be an IComparer using the ":" syntax. We then have a method inside the class which returns an integer, with a signature which accepts two People objects. This returns a number based on the CompareTo method which can compare integers, such as our age variable. You could compare height by changing only two words. e.g: returnValue = person2.Height.CompareTo(person1.Height);

(By the way, don’t worry about return value initially being set to 1, this is just to stop the “use of undefined variable” compilation error.)

We can now sort our classes by doing something like

List peopleWhoReadDannyComputerScientist = new List { };
//Imagine this list is filled with 1000 people.
peopleWhoReadDannyComputerScientist.Sort(new PeopleComparer());

The peopleWhoReadDannyComputerScientist list would now be ordered by age, allowing you to do all sorts of cool things, like binary chop search. 🙂

Its as simple as that,
Danny.

Advertisements

Tags: , , , , , ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s