Jump to content


Check out our Community Blogs

Register and join over 40,000 other developers!


Recent Status Updates

View All Updates

Photo
- - - - -

C# Flexible Sorting


  • Please log in to reply
No replies to this topic

#1 chili5

chili5

    CC Mentor

  • Expert Member
  • PipPipPipPipPipPipPipPip
  • 3038 posts
  • Programming Language:Java, C#, PHP, JavaScript, Ruby, Transact-SQL
  • Learning:C, Java, C++, C#, PHP, JavaScript, Ruby, Transact-SQL, Assembly, Scheme, Haskell, Others

Posted 20 August 2011 - 05:32 AM

C# Sorting

Sorting is such a common task that C# includes an Array class with a flexible sort method for all your sorting needs. This class is located in the System namespace so make sure you add using System; to the top of your code file.
Let us first look at a basic sort to see what the method looks likes:

 int[] v = {1, 3, 2, 4, 5};
 Array.Sort(v);

 foreach (var i in v) {
       Console.WriteLine(i);
 }
 Console.Read();

If you run the code you will see the elements of v printed one per line in increasing order. The Sort method by default sorts items in increasing order.
Change the code to this:

double[] v = { 1.0, 3.1, 2.2, 4.3, 5.4 };Array.Sort(v);
 
foreach (var i in v)
{
       Console.WriteLine(i);
}
 Console.Read();

When you run it, you will see that the items in v are still sorted in ascending order. This shows us that the Sort method is flexible enough to work with more than one data type. The question here is does it work with all types? The answer is simply no. This only works with objects that implement the IComparable interface. If we want to sort some collection that does not implement IComparable we must provide a class that implements IComparer to use for the comparison.

Before we look at sorting using IComparable and IComparar let’s look at sorting ranges of arrays.
For this, we will use the method:

 Array.Sort(Array array, int index, int length);

This method requires you to provide the first index of the range and the length of the range you want to sort.
Example:

double[] v = { 3.0, 1.1, 2.2, 4.3, 5.4 };
Array.Sort(v, 0, 2);foreach (var i in v)
{
     Console.WriteLine(i);
}
Console.Read();

In this example we are going to sort part of v from index 0 to index 1. Notice how we mentioned we are going to start at index 0 and sort the first 2 elements? Since arrays are 0 based we are only going to sort elements at position 0 to position 1. In general the range that is going to be sorted is [index, length-1].

When you run this code the output is the following:

1.3
3.0
2.2
4.3
5.4


Notice how the rest of the array after index 1 was not modified. If we wanted to start at index 2 and sort 4 elements we would write:

 Array.Sort(v, 2, 4);


This code will throw an exception if there are not enough elements to fill the range properly. This means that there must be elements in positions 2, 3, 4, 5, 6 or this will crash.

Using IComparable


The use of IComparable allows us to sort arrays in complicated ways. Let us use an example of sorting in increasing order by age followed by descending lexicographical order by name.


First, we need this class:

class Person
    {
       public string Name { get; set; }
       public int Age { get; set; }
    }
This class creates two fields and a setter and getter for the Name and Age field. This lets us change the age by doing p.Age = 10.
Create this array:

var people = new Person[4];
var p = new Person {Age = 10, Name = "chili5"};
people[0] = p;
p = new Person {Age = 8, Name = "Zeus"};
people[1] = p;
p = new Person {Age = 10, Name = "Fred"};
people[2] = p;
p = new Person {Age = 11, Name = "Bob"};
people[3] = p;

Next we have to implement the IComparable interface. Change the class declaration to this:

class Person : IComparable

The : is used to implement an interface. When we implement an interface this means that we must implement all methods defined in the interface. In this case this is the CompareTo(Object) function.

Add this method below to the Person class:


public int CompareTo(Object obj)
        {
            var p = (Person) obj;
            if (p.Age > Age) return -1;
            if (p.Age < Age) return 1;
 
            return p.Name.CompareTo(Name);
        }

This method is used to compare two Person objects and returns positive if the object that we are comparing to another object comes first and returns negative if the object that we are using to compare to another instance comes second. If they are equal we return 0.
Consider these two objects:

            var p = new Person {Age = 10, Name = "chili5"};
            var p2 = new Person {Age = 8, Name = "Zeus"};

If we do p.CompareTo(p2) the result will be -1. Why? Well first we compare the ages of the two and p’s age is 10 which is bigger than p2’s age of 8. This means that in order of age p should come after p2.
Hope this is helpful. Later we will look at LINQ and see how that implements complex sorting. Then you can make a judgement about which you prefer. In some cases it might be easier to use one over the other or in some cases such as databases it makes sense to use LINQ.
  • 0




Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download