Article Options
Premium Sponsor
Premium Sponsor

 »  Home  »  .NET Newbie  »  OOP: Create, Collect, Sort, Save and Retrieve Objects  »  Sortable Objects - Sorting Players By Name or Score
 »  Home  »  Visual Studio 2005  »  OOP: Create, Collect, Sort, Save and Retrieve Objects  »  Sortable Objects - Sorting Players By Name or Score
 »  Home  »  Windows Development  »  Visual Basic 2005  »  OOP: Create, Collect, Sort, Save and Retrieve Objects  »  Sortable Objects - Sorting Players By Name or Score
OOP: Create, Collect, Sort, Save and Retrieve Objects
by Ged Mead | Published  03/18/2007 | .NET Newbie Visual Studio 2005 Visual Basic 2005 | Rating:
Sortable Objects - Sorting Players By Name or Score

  IComparer

   Now we have a basic class and a simple collection utility in which we can store Person objects, we can turn our attention to improving the code so that Players can be easily sorted into the correct order.   But what exactly is the "correct" order of Player objects?  The VB.NET compiler certainly can't answer that question for you; the Player Class is your invention and the compiler only knows the details that you tell it.

   So, as a useful exercise for future applications, I am going to say that at times we might want the Players sorted by Name and at other times we may want them sorted by their Score.    So essentially we want to have access to multiple versions of some device that will help us sort the Players.   And of course such a device does indeed exist - and it's the IComparer Interface.

  In its most simple terms an IComparer Interface is a skeleton on which you can add flesh to the bones.   It knows how to sort (something that is quite a complex set of processes, as you'll know if you've ever attempted it yourself), but needs to know what it is being asked to sort.   

   To take a non-technical example, consider a new employee in a factory.    The new worker will understand the general principle of sorting - something is placed in a set position in an order of items.    If the worker was sent to a storehouse where there was a jumbled stack of boxes and told to "sort" them, he would have several options of how the sort should be implemented:  by size, by weight, by the contents name, by the color of the box, by serial number, etc.    In real life he would need to be told by the supervisor what sort order is required and then he would be able to get on with the job.

  And that's quite a reasonable analogy for what IComparer does.  It knows how to sort in general, but needs to be told the specifics.  Let's now look at how you use IComparer.

Sorting by Player.Name

   Amend the Player Class by adding the following lines at the end of the Class code (That is, right above the line that reads "End Class"):

Public Class CompareByNameOfPlayer
   Implements IComparer(of Player)

   Now press the Enter key and two things will happen:  The wavy blue line under the word IComparer will disappear and the outline of a new procedure will be automatically inserted into this new class.  (If necessary, also type in "End Class" to remove any remaining error message.)   The outline should look like this:

Public Function Compare(ByVal x As Player, ByVal y As Player) As Integer Implements System.Collections.Generic.IComparer(Of Player).Compare

End Function

      One of the useful features of using the Generics version of IComparer is that this Compare function knows that the comparison will be based on Player objects and so it uses the Player Type in the parameters shown there - x and y.   In the non-generics version, this would be of type Object and we would need to write more code in the function to cast from Object to Player before we could safely deal with it.  

    We will need to add some code to this skeleton procedure to give instructions on how we want it to sort. 

If x Is Nothing AndAlso y Is Nothing Then Return 0

If x Is Nothing And Not y Is Nothing Then Return 1

If Not x Is Nothing And y Is Nothing Then Return -1

Return String.Compare(x.Name, y.Name, True)

   These four lines are all that are needed to implement a valid Compare method that can be used by the compiler to sort collections of Player objects.   As you can see, the first three lines deal with cases where either or both the parameters are Nothing.     I'm not entirely convinced if these are necessary, bearing in mind that we have restricted our code to a strongly typed collection of Player objects, but it's habit I've got into pre-VB 2005 and it won't do any harm even if it does no good!

   The actual comparison of Names takes place in the last line.  Because we are dealing with a String (the Name Property is of type String) we can simply harness the String.Compare function and use this to compare two Names.  String.Compare will carry out the comparison for us  because it knows how to compare Strings alphabetically.   As you will see when we move on to the sort by Score procedure, we have to take a slightly longer way round.

   I have also included an additional parameter,  the IgnoreCase Boolean parameter which I have set to True.   This ensures that the comparisons will be made in a case insensitive manner - an approach that makes sense in this particular scenario.

   You can now try out this comparer and use it to sort the List of Players.   Put this code in the Windows Form:

PlayersList.Sort(New Player.CompareByNameOfPlayer) 
  
ListBox1.Items.Clear()
      For Each APlayer As Player In PlayersList
         ListBox1.Items.Add(String.Format("{0}, Current Score: {1}", APlayer.Name, APlayer.Score.ToString))
       Next

  Enter a few names and then click the button.  If all is well, the sorted Players List will appear.   You can add further names and click the button again to update the sort.   If your version isn't working as it should, check out the demo solution included with this article.

Sorting by Player.Score

  As I mentioned earlier, the procedure for creating a comparer to allow comparisons and sorting by the Players' Scores is similar.   Once again we will create a nested Class:

Public Class CompareByScore
Implements IComparer(Of Player)

Public Function Compare(ByVal x As Player, ByVal y As Player) As Integer _
Implements IComparer(Of Player).Compare

   If x Is Nothing AndAlso y Is Nothing Then Return 0
   If x Is Nothing And Not y Is Nothing Then Return 1
   If Not x Is Nothing And y Is Nothing Then Return -1
   If x.Score < y.Score Then
    Return -1
   ElseIf x.Score = y.Score Then
    Return 0
   Else
    Return 1
   End If
End Function
End Class

 This code is quite similar to the code we used for sorting by name, the difference being that we can't use the String.Compare method here because we are dealing with an Integer and not a String.    So you will see that last few lines of code manually compare the two values and return -1, 0 or 1 depending on which argument has the higher value.

   For testing purposes at this point you could add a second button to the form and put code in its Click event similar to the code we used in the last section when sorting by Name. i.e.

PlayersList.Sort(New Player.CompareByScore) 
  
ListBox1.Items.Clear()
      For Each APlayer As Player In PlayersList
         ListBox1.Items.Add(String.Format("{0}, Current Score: {1}", APlayer.Name, APlayer.Score.ToString))
       Next

   I have highlighted the only change that you need to make to call this variation of the sort.

   In reality, you probably won't want a separate button for each kind of sort and it's very common to use a set of Radio Buttons to allow a user to select one setting from a choice of two or more mutually exclusive options.  I won't delve into that here, but you can see a sample in the demo Solution that is included with this article.

Summary (So Far)

  So by this stage we have seen how to create a simple class that will allow us to build objects.  We saw how to create collections of those objects and here we have discussed how to sort those collections in various ways.    None of the code is very complex and you can use the same steps to create classes and sortable collections of your own.

 

 

   

Comments    Submit Comment

Comment #1  (Posted by Adam D. on 03/22/2007)
Rating
Excellent article Ged, much appreciated.
 
Comment #2  (Posted by an unknown user on 03/23/2007)
Rating
Cool!
 
Comment #3  (Posted by an unknown user on 03/28/2007)
Rating
Well done helped me get a grasp of VB.NET 2006
 
Comment #4  (Posted by an unknown user on 05/09/2007)
Rating
The explanations are adequate and the code is very clearly exposed. The code works neatly.
 
Comment #5  (Posted by mike holman on 05/09/2007)
Rating
this has proven to be a WONDERFUL application to learn from. very well explained, and i've been customizing this application to learn even more.

picking apart the code, line by line, has taught me a great deal. it's not too complex of an application, nor is it too simple. being an absolute beginner in vb.net, this site is a godsend, and it's great to have experienced programmers take the time to create tutorials like this.

thanks!!!!!
 
Comment #6  (Posted by an unknown user on 05/25/2007)
Rating
its good
 
Comment #7  (Posted by an unknown user on 06/04/2007)
Rating
Another excellent article from Ged.
He just gets the things across very much entertaining.
This guy is good !
Wonder if he is up to write a book.
 
Comment #8  (Posted by an unknown user on 07/08/2007)
Rating
Excellent. I really learned a lot from this. Keep up the good work
 
Comment #9  (Posted by an unknown user on 07/08/2007)
Rating
Excellent. I really learned a lot from this. Keep up the good work
 
Comment #10  (Posted by an unknown user on 08/10/2007)
Rating
Great, easy and comprehensive, summarization of important techniques.

Thanks a lot!
 
Comment #11  (Posted by an unknown user on 08/17/2007)
Rating
Not counting 'Hello, World!' this was my first experience with VB anything. The tutorial was well thought out and implemented. The variety topics was enough to keep my interest with out becoming over whelming.

Thank a Bazillion
 
Comment #12  (Posted by an unknown user on 08/20/2007)
Rating
Been Programming for a few years now and this is the best artical I have ran accross. I wasnt sure how they used the new generic class type for VB2005. Nice Work.
 
Comment #13  (Posted by an unknown user on 08/27/2007)
Rating
Thank you!

I have been playing with vb.net for a while and have tried following several tutorials trying to make a high score board for tetris as a learning project. I got frustrated, however, as they were all explained poorly and I struggled to follow them.

This article is very clear and well explained and I actually understand writing to and reading from binary files now. Thank you very much.
 
Comment #14  (Posted by an unknown user on 11/08/2007)
Rating
was a fun guide to recreate thnx for your time and effort Ged.
 
Comment #15  (Posted by an unknown user on 11/08/2007)
Rating
was a fun guide to recreate thnx for your time and effort Ged.
 
Comment #16  (Posted by an unknown user on 12/19/2007)
Rating
it's good pice of work about write file and read file again excellent

thanks for this article

 
Comment #17  (Posted by an unknown user on 01/23/2008)
Rating
Great stuff. Easy to understand and use even for a meathead like me. It would be wonderfull if you expanded this article to include more functions like edit, remove and delete all. Many thanks

Bob
 
Comment #18  (Posted by an unknown user on 01/25/2008)
Rating
Easy to understand.
 
Comment #19  (Posted by Clint on 04/17/2008)
Rating
Please excuse me. I've very new at .NET. When I create my form and enter the code "Dim Player1 As New Player(TextBox1.Text, CInt(TextBox2.Text))
Label3.Text = String.Format("Player Name: {0} {1}Current Score: {2}", Player1.Name,
ControlChars.CrLf, Player1.Score.ToString)" as the click event I get an error saying that label3 is not declared. How do I fix this?
 
Sponsored Links