Its quite insteresting to see that windows explorer sorts filenames etc in Native Sort where string are sorted by taking care of string and numbers as numbers. It uses StrCmpLogicalW shell function to compare by default. Siganture for this function in vb.net is
<System.Runtime.InteropServices.
DllImport("shlwapi.dll", charset:=Runtime.InteropServices.CharSet.Unicode)> _
Public Shared Function StrCmpLogicalW(ByVal strA As String, ByVal strB As String) As Int32
End Function
I tried another way of sorting by not using above mentioned function, following is an example if it interests you.
Just put a button in the form to test it
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim Filenames() As String = New String() {"3string", "2string", "st2ring", "20string", "string2", "st3ring", "string3", "string20", "st20ring"}
Array.Sort(Filenames, New CustomComparer)
MessageBox.Show(String.Join(",", Filenames))
End Sub
End Class
Public Class CustomComparer
Implements IComparer(Of String)
Private Position As Integer
Private Order As Integer = 1
Public Sub New(Optional ByVal Ascending As Boolean = True)
If Not Ascending Then
Order = -1
End If
End Sub
Public Function Compare(ByVal x As String, ByVal y As String) As Integer Implements System.Collections.Generic.IComparer(Of String).Compare
Dim res1 = System.Text.RegularExpressions.Regex.Split(x, "(\d+)", System.Text.RegularExpressions.RegexOptions.IgnoreCase).ToList
Dim res2 = System.Text.RegularExpressions.Regex.Split(y, "(\d+)", System.Text.RegularExpressions.RegexOptions.IgnoreCase).ToList
res1.RemoveAll(Function(item) item = String.Empty)
res2.RemoveAll(Function(item) item = String.Empty)
Position = 0
For Each xstr In res1
If res2.Count > Position Then
If Not IsNumeric(xstr) AndAlso Not IsNumeric(res2(Position)) Then
Dim intresult As Integer = String.Compare(xstr, res2(Position), True)
If intresult <> 0 Then
Return intresult * Order
Else
Position += 1
End If
ElseIf IsNumeric(xstr) And Not IsNumeric(res2(Position)) Then
Return -1 * Order
ElseIf Not IsNumeric(xstr) And IsNumeric(res2(Position)) Then
Return 1 * Order
ElseIf IsNumeric(xstr) And IsNumeric(res2(Position)) Then
Dim res As Integer = Decimal.Compare(Decimal.Parse(xstr), Decimal.Parse(res2(Position)))
If res = 0 Then
Position += 1
Else
Return res * Order
End If
End If
Else
Return -1 * Order
End If
Next
Return 1 * Order
End Function
End Class