Alphanumeric SortingUse an alphanumeric sort, specifying the logic as part of the IComparer Interface.
This page was last reviewed on Jan 18, 2022.
Alphanumeric sort. Strings sometimes have numbers in them. This makes sorting them more challenging. The default sort treats digits as characters and not parts of larger numbers.
A solution. A custom solution in VB.NET, called alphanumeric sorting, fixes this problem. It handles groups of digits as entire numbers, not as characters.
Data example. Some of the names begin with numbers, and some end with numbers. Often 3 digits like 100 come together—we want 100 to come after 50, not before it.
ASCII: 100F 50F SR100 SR9 Alphanumeric: 50F 100F SR9 SR100
Example. In Main we create and sort an array of highway names, some of which start with numbers. We then loop over and display those strings after sorting.
Detail The IComparer code, which I named AlphanumComparator, is more interesting. It provides the Compare method.
Tip Compare receives 2 Strings, and the loops over both of them at the same time.
Then It separates numeric parts and then parses and compares those parts with Integer.Parse.
And It continues comparing until one String is found to be unequal—either greater or lesser.
Imports System.Collections Module Module1 Sub Main() ' The input array. Dim highways() As String = {"100F", "50F", "SR100", "SR9"} ' Sort using the Comparator. Array.Sort(highways, New AlphanumComparator()) ' Loop and display highways. For Each s As String In highways Console.WriteLine(s) Next End Sub End Module ''' <summary> ''' Sorts alphanumerically. ''' </summary> Public Class AlphanumComparator Implements IComparer Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements IComparer.Compare ' [1] Validate the arguments. Dim s1 As String = x If s1 = Nothing Then Return 0 End If Dim s2 As String = y If s2 = Nothing Then Return 0 End If Dim len1 As Integer = s1.Length Dim len2 As Integer = s2.Length Dim marker1 As Integer = 0 Dim marker2 As Integer = 0 ' [2] Loop over both Strings. While marker1 < len1 And marker2 < len2 ' [3] Get Chars. Dim ch1 As Char = s1(marker1) Dim ch2 As Char = s2(marker2) Dim space1(len1) As Char Dim loc1 As Integer = 0 Dim space2(len2) As Char Dim loc2 As Integer = 0 ' [4] Collect digits for String one. Do space1(loc1) = ch1 loc1 += 1 marker1 += 1 If marker1 < len1 Then ch1 = s1(marker1) Else Exit Do End If Loop While Char.IsDigit(ch1) = Char.IsDigit(space1(0)) ' [5] Collect digits for String two. Do space2(loc2) = ch2 loc2 += 1 marker2 += 1 If marker2 < len2 Then ch2 = s2(marker2) Else Exit Do End If Loop While Char.IsDigit(ch2) = Char.IsDigit(space2(0)) ' [6] Convert to Strings. Dim str1 = New String(space1) Dim str2 = New String(space2) ' [7] Parse Strings into Integers. Dim result As Integer If Char.IsDigit(space1(0)) And Char.IsDigit(space2(0)) Then Dim thisNumericChunk = Integer.Parse(str1) Dim thatNumericChunk = Integer.Parse(str2) result = thisNumericChunk.CompareTo(thatNumericChunk) Else result = str1.CompareTo(str2) End If ' [8] Return result if not equal. If Not result = 0 Then Return result End If End While ' [9] Compare lengths. Return len1 - len2 End Function End Class
50F 100F SR9 SR100
Performance. The creation of two Strings could be eliminated. We would need to loop over characters one-by-one and compare them. It would also be possible to avoid Integer.Parse.
String Constructor
However Excessive performance optimization on the Strings might create some problems with localization.
Performance, field. It would be worthwhile to store the AlphanumComparator as a field or local variable. We do not need to recreate it more than once. This would reduce memory usage.
Notes, parsing. Another option for sorting Strings that include numbers is to first parse those Strings into objects. We could define a Class that contains the parts of the String data.
Then On that Class, we could define a Compare method that compares individual parts.
A summary. In alphanumeric sorting, we must have a way to transform digits into larger numbers. There are many ways to do this—we presented VB.NET code for a general implementation.
Dot Net Perls is a collection of tested code examples. Pages are continually updated to stay current, with code correctness a top priority.
Sam Allen is passionate about computer languages. In the past, his work has been recommended by Apple and Microsoft and he has studied computers at a selective university in the United States.
This page was last updated on Jan 18, 2022 (edit).
© 2007-2023 Sam Allen.