Jump to content
Xtreme .Net Talk

Recommended Posts

Posted

I've got a List of objects that I need to sort. There's a variety of criteria for the order that I want to sort them into, and for some of them I simply want the existing order to be maintained. For these objects I have no other record of their appropriate order than the order they are contained in in the List, and I want to preserve this. To sort them it seems sensible to use a class implementing IComparer, but the problem is, if I just return 0 for these items that I don't want sorting, they get sorted anyway (I'm not quite sure in accordance with what). So I've solved the problem by making a copy of the List before I do the sort and looking at the position of items in that. But it would be better if I didn't have to make this copy. Can you see a way around this?

 

Here's some simple code so that you can see what I've done:

 

Public Class Form1
   Friend p As New List(Of String)
   Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

       p.Add("Mouse")
       p.Add("Manatee")
       p.Add("Mole")
       p.Add("Ant")
       p.Add("Bee")
       p.Add("Walrus")
       p.Add("Monitor Lizard")

       Dim p2 As New List(Of String)

       For Each s As String In p
           p2.Add(s)
       Next

       p.Sort(New consorter(p2))

       For Each i As String In p
           Debug.Print(i)
       Next

   End Sub

   Private Class consorter

       'A class to sort a List of strings alphabetically, provided that if they begin with the same letter, they remain in the same order as before.
       Implements Collections.Generic.IComparer(Of String)

       Private presortlist As List(Of String)
       Friend Sub New(ByVal p As List(Of String))
           presortlist = p
       End Sub

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

           If x = y Then Return 0
           Dim Dif As Integer = Asc(x.Chars(0)) - Asc(y.Chars(0))
           If Dif = 0 Then
               Return presortlist.IndexOf(x) - presortlist.IndexOf(y)  'if I just return 0 here then the order of things beginning with "M" gets changed.
           Else
               Return Dif
           End If

       End Function

   End Class
End Class

  • Administrators
Posted

Returning 0 simply means the two items you are comparing are equal, this however doesn't make any claims about the items position in the sorted list.

 

i.e. If you say "Mouse" and "Manatee" are to be treated as equal by your sorting routine then Mouse, Manatee or Manatee, Mouse are both valid orderings for the results.

 

The exact order would depend on the internal sorting algorithm used by Array.Sort - which is really an implementation detail and cannot be relied upon as this could change in future anyway.

 

If you want to maintain an explicit order you would either need to handle this yourself or include the current position in the IComparer comparison.

Posting Guidelines FAQ Post Formatting

 

Intellectuals solve problems; geniuses prevent them.

-- Albert Einstein

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...