如何自定义字符串的排序顺序

时间:2013-01-02 12:52:59

标签: arrays vb.net string

我完全不习惯使用字符串数组。考虑这个例子:

我在文本框中有以下值:

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

当我对它们进行排序时,它们按字母顺序排序,如上面的列表中所示。但是,我需要它们使用@符号后面的整数值按降序排序。因此,举例来说,我希望上面的列表按如下方式排序:

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

我不知道如何按照这样的降序排列它们。

2 个答案:

答案 0 :(得分:2)

虽然在单个LINQ表达式中执行所有逻辑可以证明你有多聪明:)有时代码更容易阅读并且如果你以更冗长的方式执行它。因此,如果您不想使用LINQ,您可以创建自己的IComparer类,其中包含您的自定义排序算法:

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

在此示例中,IComparer是标准的.NET框架接口,您将在MyComparer类中实现该接口。 Compare方法(由IComparer定义)只需要两个参数并进行比较。如果x小于y(即x在排序顺序中y之前),则该方法将返回负数(例如-1)。如果x大于y,则会返回正数(例如1)。如果xy相等,则该方法将返回0.

然而,在这种情况下,由于我们要做的就是使用标准整数排序,我们可以调用Integer.CompareTo来比较两个整数,并根据需要返回负数,正数或零。

然后,当您调用Array.Sort方法时,可以为其提供一个自定义IComparer对象,以便它使用您的自定义排序算法而不是默认行为:

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

Sort方法将使用您提供的IComparer对象来执行排序。每次需要比较数组中的两个项目以查看哪个应该是第一个时,它将调用MyComparer.Compare并使用该方法返回的值来确定正确的排序。

您可以在代码中的任何位置重复使用相同的MyComparer类,使用相同的算法对项目进行排序,这是LINQ方法的另一个好处。通过实现自己的IComparer类,您可以制作各种非常强大的可自定义排序顺序。

答案 1 :(得分:1)

您想按字符串的数字部分排序吗?不需要正则表达式。

您可以使用String.SplitEnumerable.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()