Results 1 to 7 of 7

Thread: Sort a List of Custom Classes

  1. #1

    Thread Starter
    Addicted Member
    Join Date
    Dec 2013
    Location
    Earth
    Posts
    230

    Sort a List of Custom Classes

    Hey everyone!

    I need help sorting a list, containing a custom class. I want the list to be sorted alphabetically using the .ToString() function but it crashes on runtime. (My example code is below.)

    Can somebody please teach me how to use Comparers?

    Thanks a lot!

    ~Nic

    vb Code:
    1. Public Class Form1
    2.  
    3.     Dim Websites As New List(Of URL)
    4.  
    5.     Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    6.  
    7.         With Websites
    8.             .Add(New URL("VB Forums", "www.vbforums.com", True))
    9.             .Add(New URL("W3 Schools", "www.w3schools.com", False))
    10.             .Add(New URL("Google", "www.google.com", True))
    11.             .Add(New URL("Amazon", "www.amazon.com", False))
    12.         End With
    13.  
    14.         ' I need to sort the list 'Websites' by alphabetical order.
    15.         ' Using List.Sort crashes the program.
    16.         Websites.Sort()
    17.  
    18.         For Each url In Websites
    19.             ListBox1.Items.Add(url.ToString)
    20.         Next
    21.  
    22.     End Sub
    23.  
    24. End Class
    25.  
    26. ' Example class with 3 properties.
    27.  
    28. Public Class URL
    29.  
    30.     Property WebpageName As String
    31.     Property WebAddress As String
    32.     Property Favorite As Boolean
    33.  
    34.     Sub New(Name_ As String, Address_ As String, Favorite_ As Boolean)
    35.         WebpageName = Name_
    36.         WebAddress = Address_
    37.         Favorite = Favorite_
    38.     End Sub
    39.  
    40.     Public Overrides Function ToString() As String
    41.         Return WebpageName & " Url: " & WebAddress
    42.     End Function
    43.  
    44. End Class

  2. #2
    VB For Fun Edgemeal's Avatar
    Join Date
    Sep 2006
    Location
    WindowFromPoint
    Posts
    4,255

    Re: Sort a List of Custom Classes

    To sort the list of class named Websites by WebpageName ascending try,,
    Code:
    Array.Sort(Websites, Function(a, b) a.WebpageName.CompareTo(b.WebpageName))
    EDIT

    I think thats ^ for arrays , try this instead,

    Code:
    Websites.Sort(Function(a, b) a.WebpageName.CompareTo(b.WebpageName))

  3. #3

    Thread Starter
    Addicted Member
    Join Date
    Dec 2013
    Location
    Earth
    Posts
    230

    Re: Sort a List of Custom Classes

    I guess that works! However, I changed it to:
    Code:
    Websites.Sort(Function(a, b) a.ToString().CompareTo(b.ToString))
    ...so it was sorted by .ToString.

    But if it is really that simple, then why does Microsoft have such a lengthy example and long process in https://msdn.microsoft.com/en-us/lib...v=vs.110).aspx ?

  4. #4
    VB For Fun Edgemeal's Avatar
    Join Date
    Sep 2006
    Location
    WindowFromPoint
    Posts
    4,255

    Re: Sort a List of Custom Classes

    I normally use an API so it sorts like Windows Explorer does, this way strings are sorted logically, so for example numbers in string are what you'd expect, 1, 2, 10, (and not 1, 10 ,2), like I have a list of tv shows and inside that list is a list of episodes for that show, when i want to sort the episodes by name I use a comparer I made...

    Code:
    ' sort episodes by name
    TvShows(index).Episodes.Sort(New LogicalEpisodeNameComparer)
    
    ' the comparer,
    Public Class LogicalEpisodeNameComparer
        Implements IComparer(Of EpisodeInfo)
        Private Declare Unicode Function StrCmpLogicalW Lib "shlwapi" (ByVal s1 As String, ByVal s2 As String) As Integer
        Private Function Compare(x As EpisodeInfo, y As EpisodeInfo) As Integer Implements System.Collections.Generic.IComparer(Of EpisodeInfo).Compare
            Return StrCmpLogicalW(x.EpisodeName, y.EpisodeName)
        End Function
    End Class
    
    ' episode info class
    Public Class EpisodeInfo
        Public Property EpisodeName As String
        Public Property EpisodeURL As String
        Public Property Watched As Boolean
        Public Property DateAdded As Date
        Public Sub New(episodeName As String, episodeUrl As String, watched As Boolean, dateAdded As Date)
            Me.EpisodeName = episodeName
            Me.EpisodeURL = episodeUrl
            Me.Watched = watched
            Me.DateAdded = dateAdded
        End Sub
    End Class
    
    Public Class TVshow
        Public Property Name As String
        Public Property Ratings As Single
        Public Property Episodes As List(Of EpisodeInfo)
    End Class
    Last edited by Edgemeal; Apr 22nd, 2016 at 11:40 AM. Reason: typos

  5. #5
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Sort a List of Custom Classes

    Quote Originally Posted by NinjaNic View Post
    But if it is really that simple, then why does Microsoft have such a lengthy example and long process in https://msdn.microsoft.com/en-us/lib...v=vs.110).aspx ?
    Firstly, it's demonstrating more than one way to sort and secondly there is always a certain amount of setup required in order to demonstrate a simple principle. The part from that lengthy example that corresponds to what you've been shown here is just this:
    Code:
            ' This shows calling the Sort(Comparison(T) overload using 
            ' an anonymous delegate method. 
            ' This method treats null as the lesser of two values.
            parts.Sort(Function(x As Part, y As Part)
                                 If x.PartName Is Nothing AndAlso y.PartName Is Nothing Then
                                     Return 0
                                 ElseIf x.PartName Is Nothing Then
                                     Return -1
                                 ElseIf y.PartName Is Nothing Then
                                     Return 1
                                 Else
                                     Return x.PartName.CompareTo(y.PartName)
                                 End If
                             End Function)
    That is just as simple as what you've been shown here except that it allows for either or both of the compared properties to not have a value. That code snippet alone would be useless without the setup of defining the PartClass and the PartName property though.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  6. #6

    Thread Starter
    Addicted Member
    Join Date
    Dec 2013
    Location
    Earth
    Posts
    230

    Re: Sort a List of Custom Classes

    @Edgemeal: Interesting code. To me it looks like it's just a complicated way to compare the EpisodeName property but I'm probably wrong.

    @jmc: Ok so that's more of a breakdown of the one-line..I'm guessing the -1, 1, and 0 is supposed to be moving the object up, down, or keep it where it is in the list?

    Oh, and, thanks to you both for the help! I got what I needed and more, as usual.

  7. #7
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Sort a List of Custom Classes

    Quote Originally Posted by NinjaNic View Post
    @jmc: Ok so that's more of a breakdown of the one-line..I'm guessing the -1, 1, and 0 is supposed to be moving the object up, down, or keep it where it is in the list?
    Sorting a list of items involves repeatedly comparing pairs of items and rearranging them if appropriate. To that end, the Sort method requires a method that can be called repeatedly for pairs of items in the list and will provide an indication of whether the items need to be rearranged. If that method returns zero then it indicates that the items are considered equivalent for the purposes of ordering. A value less than zero indicates that the first item is considered the lesser and a value greater than zero indicates that the second value is the lesser. While any non-zero values will, it is convention to use -1 and 1 unless there is a more intuitive option.

    If you call Sort with no parameters then it relies on the IComparable.CompareTo implementation of the items themselves. If you pass an object that implements IComparer then it relies on the Compare method of that object. If you pass a Comparison(Of T) delegate then the method it refers to must provide the same behaviour.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width