Sorting a list / Implementation of IComparable
-
I have a list of objects. When trying to sort the list, I receive an error "error while comparing two elements of the array". Inner Exception is "At least one object must implement IComparable." (Please note: I'm using the german version of VB Express and therefor I had to re-translate the error messages. So the original english error messages may be a little different). Here's the code I have so far:
Public Class cl_country
Private m_Name As StringPublic Property Name() As String
Get
Return m_Name
End Get
Set(ByVal value As String)
m_Name = value
End Set
End PropertyEnd Class
Public Class Form1
Private my_List As New List(Of cl_country)
Private country_1 As New cl_country
Private country_2 As New cl_country
Private country_3 As New cl_country
Private z As IntegerPrivate Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Init()
GUI_Output(ListBox1)
my_List.Sort()
GUI_Output(ListBox2)
End SubPrivate Sub Init()
country_1.Name = "Germany"
country_2.Name = "Brazil"
country_3.Name = "UK"
my_List.Add(country_1)
my_List.Add(country_2)
my_List.Add(country_3)
End SubPrivate Sub GUI_Output(ByVal a_listbox As ListBox)
a_listbox.Items.Clear()
For z = 1 To my_List.Count
a_listbox.Items.Add(my_List.Item(z - 1).Name)
Next
End SubEnd Class
I have understood that VB is unable to sort objects and that I need to provide a method to do so. I had a look at IComparable and it's examples in the Object Browser but I did not understand the examples. Can anyone help me with this ?
-
Classes that implement IComparable have a CompareTo method. If you take a look at an integer or string or many other objects you'll see they have this method. All the CompareTo method does is accepts another object and returns a value indicating the current objects relative position with the object passed. The return value would be 1, 0, -1 for "greater then", "equal to", "less then". It's this method that allows any object to be sorted becaues all you need to know in order to sort a list of objects is how one of these objects compares to another.
In order to use the interface just type "implements IComparable(of cl_country)" just under your class declration and then hit enter. When you hit enter the appropriate method declarations for the interface will be created for you. In this case there is only one method 'CompareTo'. It's your responsibilty to add the code into this method that compares the current object with the object passed and return a relative value.
An example may help.
Public Class Form1 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click ' Create three people objects Dim obj1 As New Person("FirstPerson", 29) Dim obj2 As New Person("SecondPerson", 47) Dim obj3 As New Person("ThirdPerson", 10) ' Create a list of people and add the objects I've created Dim people As New List(Of Person) people.AddRange(New Person() {obj1, obj2, obj3}) ' Sort the list people.Sort() ' Display each of the people in the list showing they've been ' sorted is Ascending order by age For Each p As Person In people Console.WriteLine("{0} is {1} years old", p.Name, p.Age) Next End Sub End Class ' A person with a name and age ' This class uses IComparable so it can be sorted Public Class Person Implements IComparable(Of Person) Public Age As Integer ' Persons age Public Name As String ' Persons name ' Constructor Public Sub New(ByVal name As String, ByVal age As Integer) Me.Age = age Me.Name = name End Sub ' CompareTo method is part of the IComparable interface ' This method will return the relative value of this object with the passed ' object. 1 = Greater then 0 = Equal To -1 = Less then ' I'll be sorting on age so this method will compare the age fields Public Function CompareTo(ByVal other As Person) As Integer Implements System.IComparable(Of Person).CompareTo ' I've actually used more code here then I need to drive the ' example home. You can clearly see how I've done the comparison ' with this if statement. If Me.Age > other.Age Then Return 1 ElseIf Me.Age = other.Age Then Return 0 Else Return -1 End If ' In this case I really could have used the integers CompareTo method ' and simply used the next commented line of code instead of ' the if statement above. 'Return Me.Age.CompareTo(other.Age) ' The if statement above will cause my peson objects to be sorted in Ascending order ' However this could easily be changed with the following commented code. ' Notice how I'm now passing a -1 when this object's age is greater then the passed object's age ' and a 1 when this object is less then the other object. By reversing the return value I'll reverse ' the sort order 'If Me.Age > other.Age Then ' Return -1 'ElseIf Me.Age = other.Age Then ' Return 0 'Else ' Return 1 'End If End Function End Class
-
Many thanks for your help TwoFaced. That was exactly what I was looking for.
Post a reply
Quick links
Recent activity
- arif ahmad replied to How to receive data in web ...
- William Thompson replied to What is the name of the Win...
- Sameera Piyadigamage replied to Point of Sale Developers: H...
- Scott Carline replied to 4 x C# Developers for large...
- Rajendra Dhakal replied to Restore SQL Server text dat...
- cloud rainda replied to How to convert between TS f...
Enter your message below
Sign in or Join us (it's free).