views:

37

answers:

2

How CompareTo method logic works in List sort function.

public class person : IComparable
{
    string firstName;
    string lastName;

    public int CompareTo(object obj)
    {
        person otherPerson = (person)obj;
        if (this.lastName != otherPerson.lastName)
            return this.lastName.CompareTo(otherPerson.lastName);
        else
            return this.firstName.CompareTo(otherPerson.firstName);
    }

    public person(string _firstName, string _lastName)
    {
        firstName = _firstName;
        lastName = _lastName;
    }

    override public string ToString()
    {
        return firstName + " " + lastName;
    }
}

List<person> l = new List<person>();
l.Add(new person("Mark", "Hanson"));
l.Add(new person("Kim", "Akers"));
l.Add(new person("Zsolt", "Ambrus"));

l.Sort();

foreach (person p in l)
    Console.WriteLine(p.ToString());
+1  A: 

It sorts by last name, then first name.

If two people have the same last name, the if statement will end up comparing by first name.
Otherwise, it will compare by last name.

SLaks
+1  A: 

When you invoke the Sort method on a generic list (List in your case), behind the scenes, the implementation of Sort will check if the type of the list (the person class) implements the IComparable interface, and if it does it will invoke the CompareTo member to perform comparisons between elements of the list to perform the sort. The fact that the person class implements IComparable is interpreted as a "contract" that specifies that the person class will have a method called CompareTo.

The implementation of Sort can use a snippet such as the following to compare to elements of the list:

T aPerson;
T anotherPerson;
int compareResult;

if(aPerson is IComparable)
{
    compareResult = (aPerson as IComparable).CompareTo(anotherPerson);
}

The CompareTo method always compares the object it is invoked on to the parameter and the meaning of the return value is always the same:

* if the two objects are "equal", it returns 0
* if the object you are comparing to is "less than" - in a sorted list it goes before - the object you are invoking CompareTo on, it returns -1
* if the object you are comparing to is "greater than" - in a sorted list it goes after - the object you are invoking CompareTo on, it returns -1

Internally, the Sort method may employ a number of algorithms to actually perform the sort but they all revolve around comparisons. For example, the following would be a naive implementation of bubble sort which is very simple to follow and illustrates what happens behind the scenes very well:

procedure bubbleSort( A : list of sortable items ) defined as:
  do
    swapped := false
    for each i in 0 to length(A) - 2 inclusive do:
      if A[i].CompareTo(A[i+1]) > 0 then
        swap( A[i], A[i+1] )
        swapped := true
      end if
    end for
  while swapped
end procedure
Miky Dinescu
it is hard to understand compareTo processing.
Novice Developer
what do you mean by compareTo processing?
Miky Dinescu
Ok I got your bubblesort example, and I mean same processing which you wrote in your answer. thank you.
Novice Developer
Just for the record, `List<T>.Sort` is documented as using an unstable QuickSort: See the Remarks section of http://msdn.microsoft.com/en-us/library/w56d4y5z.aspx
LukeH
Thanks @LukeH for pointing that out. I considered the actual implementation not important for the purpose of the discussion - regardless of the algorithm they all get down to comparisons between elements. I chose BubbleSort as an example because it is really easy to follow..
Miky Dinescu
There's always a problem with using bubble-sort in an example; someone might actually use the code! It's always worth adding a caveat when you use it as an example.
Jon Hanna