我对使用字符串数组完全陌生。考虑这个例子:
我在文本框中有以下值:
bufallo@2000
lice@20
cell@1
rat@150
cow@10000
当我对它们进行排序时,它们按字母顺序排序,如上面的列表所示。但是,我需要它们使用 @ 符号后面的整数值按降序排序。因此,例如,我希望将上面的列表排序如下:
cow@10000
bufallo@2000
rat@150
lice@20
cell@1
我不知道如何像这样按降序排列它们。
虽然在单个 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)。如果x
和y
相等,则该方法将返回 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
类允许您制作各种非常强大的可自定义排序顺序。
您想按字符串的数字部分排序吗?不需要正则表达式。
您可以使用String.Split
和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()