TheDeveloperBlog.com

Home | Contact Us

CSharp | Java | Python | Swift | GO | WPF | Ruby | Scala | F# | JavaScript

<< Back to VBNET

VB.NET Alphanumeric Sorting

Use an alphanumeric sort, specifying the logic as part of the IComparer Interface.
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 custom solution in VB.NET, called alphanumeric sorting, fixes this problem.Sort
ASCII Sort: 100F 50F SR100 SR9 Alphanumeric Sort: 50F 100F SR9 SR100
This program has two parts: the Main subroutine, and the AlphanumComparator implementation. 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.

IComparer: The IComparer code, which I named AlphanumComparator, is more interesting. It provides the Compare method.

Tip: In a nutshell Compare receives two 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.

VB.NET program that sorts alphanumerically 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 Output 50F 100F SR9 SR100
Performance. There are some inefficiencies here. The creation of two Strings, with the New String constructors, 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 ConstructorInteger.Parse

However: Excessive performance optimization on the Strings might create some problems with localization.

Also, for using the AlphanumComparator, it would be worthwhile to store the object instance as a field or local variable. We do not need to recreate it more than once. This would reduce memory usage.
Another option for sorting Strings that include numbers is to first parse those Strings into objects. We could define a custom Class that contains the parts (in any representation) of the String data.

Then: On that Class, we could define a Compare method that compares individual parts.

Class

Tip: Perhaps the best optimization for this IComparer implementation is not to use it unless necessary.

And: The sorting mechanisms built into the .NET Framework are better in many contexts.

Summary. Alphanumeric sorting poses several difficulties. 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.
© TheDeveloperBlog.com
The Dev Codes