简体   繁体   中英

How to customize sort order of strings

I am completely new to using string arrays. Consider this example:

I have the following values in a text box:

bufallo@2000
lice@20
cell@1
rat@150
cow@10000

When I sort them, they are sorted alphabetically, as in the list above. However, I need them to sort in descending order using the integer value that follows the @ symbol. So, for instance, I want the above list to be sorted like this:

cow@10000
bufallo@2000
rat@150
lice@20
cell@1

I have no idea on how to arrange them in descending order like that.

While doing all your logic in a single LINQ expression can prove how clever you are :) sometimes the code is just easier to read and follow if you do it in a more verbose fashion. So, if you don't want to use LINQ, you could create your own IComparer class which contains your custom sorting algorithm:

Public Class MyComparer
    Implements IComparer(Of String)

    Public Function Compare(ByVal x As String, ByVal y As String) As Integer Implements IComparer(Of String).Compare
        Dim xParts() As String = x.Split("@"c)
        Dim yParts() As String = y.Split("@"c)

        'Get the integer value (after the @ symbol) of each parameter
        Dim xValue As Integer = 0
        Dim yValue As Integer = 0
        If xParts.Length = 2 Then
            Integer.TryParse(xParts(1), xValue)
        End If
        If yParts.Length = 2 Then
            Integer.TryParse(yParts(1), yValue)
        End If

        'Compare y-to-x instead of x-to-y because we want descending order
        Return yValue.CompareTo(xValue)
    End Function
End Class

In this example, IComparer is a standard .NET framework interface, which you are implementing in your MyComparer class. The Compare method (as defined by IComparer ) simply takes two parameters and compares them. If x is less than y (ie x comes before y in the sort-order), the method will return a negative number (eg -1). If x is greater than y , it will return a positive number (eg 1). And if x and y are equal, then the method will return 0.

In this case, however, since all we want to do is use the standard integer sorting, we can just call Integer.CompareTo which compares two integers and returns the negative, positive, or zero, as appropriate.

Then, when you call the Array.Sort method, you can give it one of your custom IComparer objects so that it uses your custom sorting algorithm instead of the default behavior:

Dim arrayToSort() As String = New String() {"bufallo@2000", "lice@20", "cell@1", "rat@150", "cow@10000"}
Array.Sort(arrayToSort, New MyComparer())

The Sort method will use the IComparer object that you gave it to perform the sorting. Each time it needs to compare two items in the array to see which should come first, it will call MyComparer.Compare and use the value returned by that method to determine the proper sorting.

You can re-use the same MyComparer class everywhere in your code that you need to sort items using that same algorithm, which is another benefit over the LINQ approach. Implementing your own IComparer classes allows you to make all sorts of very powerful customize-able sort orders.

You want to order by the numeric part of the string? No need for Regex.

You can use String.Split and Enumerable.OrderByDescending :

Dim number As Int32 = Int32.MinValue
Dim orderedLines = From line In TextBox1.Lines
                   Let parts = line.Split("@"c)
                   Let numericPart = parts.Last()
                   Let success = Int32.TryParse(numericPart, number)
                   Select LineInfo = New With {line, number}
                   Order By LineInfo.number Descending
                   Select LineInfo.line
' if you want to reassign it to the TextBox:
TextBox1.Lines = orderedLines.ToArray()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM