DevPinoy.org
A Filipino Developers Community
   
Sorting a Generic List of Object in C# using IComparable and Anonymous Delegates

A few weeks ago I wrote an article on how to use IComparer and how it was easy it is to create a custom comparer to sort our objects. This time we'll talk creating a default sort mechanism for our objects by using IComparer's relative, the interface IComparable.  We'll also be touching Anonymous Delegates a bit.

I don't want to discuss the technical detail as I want to because it might bore the reader of this article, in turn i'll just be showing the code and some relative examples :). Also, we'll start with the same flow on how we demonstrated the last sample. I think story telling can be used effectively to demonstrate programming problems(much like code puzzles in college).  Enough with the intro and back to code.

Our story starts with Rolvin. Rolvin is software engineer in the business district of Makati, a huge IT hub in the Philippines. Rolvin works hard usually doesn't go to lunch.. but when he does expect him to go around the block to check out girls in the restaurants and food courts around his office. One day while sitting at a popular burger shop an idea popped into Rolvin's mind. He realized that he is already 24, never had a girlfriend in his life and he thought to himself that it's about time for him to go out and date somebody. He closed his eyes for a second and had this wonderful bliss striking his mind. He said "I'll date the girls I've met around this joint!". 

But our hero has a problem. He doesnt know who to date.

He has seen alot of girls around the area, met and chatted with some of them, got their numbers but he never thought about courting or asking some for a date up until now.  Rolvin is smart.. he decided to pullout a tissue paper and listed all the names of the girls he met and some basic information about them. There are 3 things that he thought were important. First, the girl should have a name. Second, the girl that he will down on his list should have an age. And lastly, the "cuteness factor". He thinks that he is a very handsome guy and he deserves somebody equal or greater than his looks(talk about ego;)).

Ok, now this is our chance to help Rolvin. We need to create the Girl class first.

The Girl from Rolvin's definition should have a Name, Age and Cuteness Factor. The Girl class should also implement IComparable because we need have pre-defined sort mechanism in our class. Making a class inherit from IComparable is like giving the class the ability of "self-conciousness" wherein a class can decided whether it is greater or less than other classes. The listing below shows how the class would look like without the implementation of the sort inside the CompareTo Method.

[CODE: Girl.cs]

using System;
using System.Collections.Generic;
using System.Text;

namespace RolvinsGirlSelector
{
   class Girl: IComparable<Girl>
   {
      private string _name;
      private int _age;
      private int _cutenessFactor;

      /// <summary>
      /// The name of the girl.
      /// </summary>
      public string Name
      {
         get
         {
            return _name;
         }
         set
         {
            _name = value;
         }
      }

      /// <summary>
      /// The age of the girl.
      /// </summary>
      public int Age
      {
         get 
         { 
            return _age;
         }
         set
         {
            _age = value;
         }
      }

      /// <summary>
      /// A "Rolvin" defined scaling factor that is from 0 to 5.
      /// 0 being the lowest(not that appealing) and 5 being the highest(hot. extremely his type).
      /// </summary>
      public int CutenessFactor
      {
         get
         {
            return _cutenessFactor;
         }
         set
         {
            _cutenessFactor = value;
         }
      }

      public Girl() { }
      public Girl(string name, int age, int cutenessFactor)
      {
         this._name = name;
         this._age = age;
         this._cutenessFactor = cutenessFactor;
      }

      #region IComparable<Girl> Members

      public int CompareTo(Girl other)
      {
         throw new Exception("The method or operation is not yet implemented.");
      }

      #endregion
   }
}

Rolvin decided that the name doesn't matter to him. All he is concerned of is that the girl's age, availability and cuteness factor. The name is only there for him to serve as an identifier. Rolvin thinks about the names and information of the girls he met and listed each and everyone one of them.

[CODE: Program.cs]

using System;
using System.Collections.Generic;
using System.Text;

namespace RolvinsGirlSelector
{
   class Program
   {
      static void Main(string[] args)
      {
         //A list of girls Rolvin would love to date
         List<Girl> girls = new List<Girl>();

         girls.Add(new Girl("Joan", 18, 4));
         girls.Add(new Girl("Kristine", 19, 3));
         girls.Add(new Girl("Maria", 18, 2));
         girls.Add(new Girl("Luisa", 20, 2));
         girls.Add(new Girl("Heart", 21, 5));
         girls.Add(new Girl("Lynn", 20, 4));
         girls.Add(new Girl("Phoebe", 22, 4));
         girls.Add(new Girl("Anna", 23, 5));
         girls.Add(new Girl("Allysa", 22, 5));
         girls.Add(new Girl("Connie", 18, 5));
         girls.Add(new Girl("May", 20, 5));
         girls.Add(new Girl("Iyah", 24, 3));
         girls.Add(new Girl("Rapunzel", 24, 5));

         foreach (Girl g in girls)
         {
            Console.WriteLine("{0,-10} {1, -5} {2}", g.Name, g.Age, g.CutenessFactor);
         }
         Console.ReadLine();
      }
   }
}

/*Result

Joan       18    4
Kristine   19    3
Maria      18    2
Luisa      20    2
Heart      21    5
Lynn       20    4
Phoebe     22    4
Anna       23    5
Allysa     22    5
Connie     18    5
May        20    5
Iyah       24    3
Rapunzel   24    5

*/

Now that a list is created, Rolvin needs to decide on the criteria for the ranking. He closed his eyes once again and after a few seconds decided that he wants to sort the girls first by their cuteness factor.

[Modified CompareTo in Girls.cs]

#region IComparable<Girl> Members

public int CompareTo(Girl other)
{
   return other.CutenessFactor.CompareTo(this.CutenessFactor);
}

#endregion

Looking at the list again after adding the line

girls.Sort();

Before calling the print code resulted to this

/*Result

Allysa     22    5
Heart      21    5
Anna       23    5
Rapunzel   24    5
May        20    5
Connie     18    5
Phoebe     22    4
Joan       18    4
Lynn       20    4
Kristine   19    3
Iyah       24    3
Luisa      20    2
Maria      18    2

*/

Now he knows who likes the most among the 13 girls that he selected.. but, there is a tie amongst the girls and he is still undecided on who to ask for a date. He looked at the list again and said to himself that he wants to date someone who is closer to his age. With that he modified his sorting criteria by adding the age to the criteria.

[Modified CompareTo in Girls.cs]

#region IComparable<Girl> Members

public int CompareTo(Girl other)
{
   /* LEGEND
   * < 0 means that this object is less than other
   * 0 means that both objects are equal
   * > 0 means that this object is greater than other
   * */


   int returnValue = -1;
   if (other.CutenessFactor > this.CutenessFactor)
   {
      returnValue = 0;
   }
   else if (other.CutenessFactor == this.CutenessFactor)
   {
      returnValue = other.Age.CompareTo(this.Age);
   }

   return returnValue;
}

#endregion

Looking at the code again the result was this list

/*Result

Rapunzel   24    5
Anna       23    5
Allysa     22    5
May        20    5
Connie     18    5
Phoebe     22    4
Iyah       24    3
Kristine   19    3
Luisa      20    2
Joan       18    4
Heart      21    5
Lynn       20    4
Maria      18    2

*/

He now knows that Rapunzel is the first girl that she would ask out... He saw his friend Modchip and told him about his plans. To his amazement Modchip was also thinking of courting somebody.. Modchip the heartrob also has his own list which is surprisingly the same as what Rolvin have.. with one difference. Modchip rated the girls the same on the cuteness factor but he preffers the younger girls(OMG).

This time instead of using the CompareTo Method we will use an anonymous delegate to re-wire the sort method. After all, we don't want to modify the default comparer.

[Modified Sort Method with Anonymous Delegate]

girls.Sort(
   delegate(Girl g1, Girl g2)
   {
      int returnValue = -1;
      if (g2.CutenessFactor > g1.CutenessFactor)
      {
         returnValue = 0;
      }
      else if (g2.CutenessFactor == g1.CutenessFactor)
      {
         //descending
         returnValue = g1.Age.CompareTo(g2.Age);
      }
      return returnValue; 
   }
);

Then they compared their list:

/*Result

Rolvin's Selection
Rapunzel   24    5
Anna       23    5
Allysa     22    5
May        20    5
Connie     18    5
Phoebe     22    4
Iyah       24    3
Kristine   19    3
Luisa      20    2
Joan       18    4
Heart      21    5
Lynn       20    4
Maria      18    2
-----
Modchip's Selection
Connie     18    5
May        20    5
Heart      21    5
Allysa     22    5
Anna       23    5
Rapunzel   24    5
Joan       18    4
Lynn       20    4
Phoebe     22    4
Kristine   19    3
Iyah       24    3
Maria      18    2
Luisa      20    2

*/

Sweet! Now they can start the dating process :) And Rolvin lived happily single after. LOL!

Hope you learned something out of this article. Thanks!


Posted 03-23-2007 11:59 AM by keithrull

Comments

lamia wrote re: Sorting a Generic List of Object in C# using IComparable and Anonymous Delegates
on 03-23-2007 10:53 PM

I'll be sure to test this on Java by Monday with the Comparable interface!

cruizer wrote re: Sorting a Generic List of Object in C# using IComparable and Anonymous Delegates
on 03-24-2007 2:22 AM

alaskado si Rolvin ah Stick out tongue

David Brabant wrote re: Sorting a Generic List of Object in C# using IComparable and Anonymous Delegates
on 03-24-2007 10:17 AM

> Hope you learned something out of this article.

Yep. An article offering to sort girls according to a "cuteness factor" and not showing picture of them is definitely missing something.

keithrull wrote re: Sorting a Generic List of Object in C# using IComparable and Anonymous Delegates
on 03-24-2007 12:35 PM

@cruizer: nah, this was just an example. i wasnt trying to make fun of Rolvin. I was just trying to demonstrate a real world example on how to solve sorting issues with IComparable<T> and Anonynous Delegates.

@david: hmmm.., that sounds like a good article to work on. I'll build an ASP.NET sample for that article.

Keith Rull wrote Find items inside a Generic List using the old approach, the cool approach and the super duper cool approach.
on 03-26-2007 4:44 PM

A few days ago we helped Rolvin sort the list of girls he wants to date .. this time we'll help him find

jakelite wrote A Tribute to the Unsung Heroes of C#’s Functional Revolution
on 03-29-2007 8:02 AM

Many of us may not have noticed it but C# 2.0 gave us several really cool delegates and methods aimed

jakelite wrote re: Sorting a Generic List of Object in C# using IComparable and Anonymous Delegates
on 03-29-2007 8:04 AM

Many of us may not have noticed it but C# 2.0 gave us several really cool delegates and methods aimed at providing a gentle transition to the functional programming concepts introduced in C# 3.0 and Linq...

kagemusha wrote re: Sorting a Generic List of Object in C# using IComparable and Anonymous Delegates
on 07-25-2007 5:30 AM

Thanks for this post, it is useful.

I wonder the time complexity of the sort algorithm, do you have any idea about the sorting algorithm they use?

Regards

Bryan wrote re: Sorting a Generic List of Object in C# using IComparable and Anonymous Delegates
on 10-08-2007 5:18 AM

kagemusha:  With VS 2008, they will be releasing the source code to the .NET Framework, so you will actually be able to step through the algorithm with the debugger.  Mroe info here:

cplus.about.com/.../000190.htm

Patrick wrote re: Sorting a Generic List of Object in C# using IComparable and Anonymous Delegates
on 04-02-2008 10:44 AM

Saw it.

Read it.

Used it.

Sorted.

Rolvin wrote re: Sorting a Generic List of Object in C# using IComparable and Anonymous Delegates
on 10-01-2008 8:11 AM

At least I can sort lists now :)

Thanks.

Sandy wrote re: Sorting a Generic List of Object in C# using IComparable and Anonymous Delegates
on 10-01-2008 1:50 PM

This website is really greate. this is helpful.

Thank you very much. I like the way you explain so it will be easy to keep in mind.

Thanks again

PDM wrote re: Sorting a Generic List of Object in C# using IComparable and Anonymous Delegates
on 10-31-2008 2:38 AM

Spot on - cheers :o)

naresh wrote re: Sorting a Generic List of Object in C# using IComparable and Anonymous Delegates
on 10-31-2008 4:37 PM

Sweet!!! worked like a charm. Thank you very much for helping us understanding the concept with real example. I have implemented in my program with out much effort.

Shweta wrote re: Sorting a Generic List of Object in C# using IComparable and Anonymous Delegates
on 11-13-2008 3:56 AM

Interesting example. Was easy to understand. Thanks...

Rana wrote re: Sorting a Generic List of Object in C# using IComparable and Anonymous Delegates
on 11-21-2008 5:36 AM

Cool Dude. You just helped Rolvin to find a girl and you made sure that we all understand how easy it is to date a girl of choice using GENRICS. Wonderful article.

Keep writing and my hearty appreciations for your great contribution.

Cheers,

Rana

Bangalore

Copyright DevPinoy 2005-2008