Reputation: 163
I am trying to sort a list of string into a very particular order. I have a list of items which come in the format of "X123XXX" where X can be a letter, and the 123 can be any number.
Dim AList As New List(Of String)
AList.Add("B200")
AList.Add("A100X")
AList.Add("A100XY")
AList.Add("A100XYZ")
AList.Sort()
'Actual Return in order (AList(1).tostring etc.)
'A100X
'A100XY
'A100XYZ
'B200
'Desired Return
'A100XYZ
'A100XY
'A100X
'B200
The problem I have is that Not only do I need to sort the Numbers Ascending and Letters Descending, but I also need to sort the first letter Ascending.
I was hoping that, as the parts are always in the same format (letter + 3 numbers + Optional up to 3 letters) - that I could just select the first 4 and sort that ASC and then DESC on the last 3. But i have no idea how to do that in vb.net. I've had a look around, and can only find the IComparable stuff, which doesn't seem like it would be very useful.
Upvotes: 2
Views: 6282
Reputation: 6738
An alternate approach to the anonymous function, create a Class that implements IComparer(Of String)
:
Private Class CodeComparer
Implements System.Collections.Generic.IComparer(Of String)
Function Compare(ByVal a As String, ByVal b As String) As Integer _
Implements IComparer(Of String).Compare
Dim result As Integer = a.Substring(0, 4).CompareTo(b.Substring(0, 4))
If result = 0 Then
result = a.Substring(4).CompareTo(b.Substring(4)) * -1
End If
Return result
End Function
End Class
This sorts by the first 4 characters in ascending order, then by the remaining characters in decending order (hence the * -1
).
You can then sort the list using:
items.Sort(New CodeComparer())
Edit: You can also use the same algorithm with an anonymous function passed to the Sort
method.
items.Sort(Function(a, b)
Dim result As Integer = a.Substring(0, 4).CompareTo(b.Substring(0, 4))
If result = 0 Then result = a.Substring(4).CompareTo(b.Substring(4)) * -1
Return tmp
End Function)
Upvotes: 2
Reputation:
You can get what you want by relying on some LINQ
methods (OrderBy
, ThenBy
, etc.); they allow you to perform all the modifications you need.
Code delivering what you want:
AList = AList.OrderBy(Function(x) x.Substring(0, 1)).ThenBy(Function(x) Convert.ToInt32(x.Substring(1, 3))).ThenByDescending(Function(x) x.Substring(4)).ToList()
UPDATE
The code above orders the last part (i.e., letters from the 5th position until the end) in alphabetically descending order; but apparently the OP wants this last sorting to be performed on account of the length of the strings (i.e., longest one first and shortest one last). The following code delivers such a behaviour:
AList = AList.OrderBy(Function(x) x.Substring(0, 1)).ThenBy(Function(x) Convert.ToInt32(x.Substring(1, 3))).ThenByDescending(Function(x) x.Substring(4).Length).ToList()
Upvotes: 5