我有一个包含地址的Tlist。当我对列表进行排序时,地址中的数字被认为是一个字符串,并且它没有正确排序。我应该如何对列表进行排序?
Dim sortme As List(Of data) = tempdata 'main list containing addresses as strings.
sortme.Sort(Function(p1 As data, p2 As data) numorder(p1.Value).CompareTo(numorder(p2.Value)))
Private Function numorder(ByVal str As String)
Try
Dim words() As String = str.Split(" "c) 'read string up to first space (for number)
Return Convert.ToInt32(words(0))
Catch ex As Exception
End Try
End Function
当前输出示例:
1001 street name
103 street name
1021 street name
应该是:
103 street name
1001 street name
1021 street name
答案 0 :(得分:1)
想法是编写自己的比较器,首先考虑数字前缀,然后是字符串本身。然后可以在任何地方使用此比较器,例如在LINQ OrderBy()
中。这里的一个例子在c#中看到下面的完整VB.NET版本。
public class StreetComparer : IComparer<string>
{
public int Compare(string x, string y)
{
int indexOfSpaceX = x.IndexOf(' ');
string numericalPartX = x.Substring(0, indexOfSpaceX);
int indexOfSpaceY = y.IndexOf(' ');
string numericalPartY = y.Substring(0, indexOfSpaceY);
int numberX;
int numberY;
if(!int.TryParse(numericalPartX, out numberX) ||
!int.TryParse(numericalPartY, out numberY))
{
//Some code to handle the case where number is missing
throw new ArgumentException();
}
if (numberX!=numberY)
{
return numberX-numberY;
}
string textPartX = x.Substring(indexOfSpaceX + 1);
string textPartY = x.Substring(indexOfSpaceY + 1);
return String.Compare(textPartX, textPartY, true, CultureInfo.CurrentCulture);
}
}
class Program
{
static void Main(string[] args)
{
var myStreets = new[] {"01 aaa", "02 bbb"};
var result = myStreets.OrderBy(s => s, new StreetComparer());
}
}
现在一个VB.NET版本完全适合你的用例一个List,其中的类按属性排序:
Public Class StreetComparer
Implements IComparer(Of String)
Public Function Compare(x As String, y As String) As Integer
Dim indexOfSpaceX As Integer = x.IndexOf(" "C)
Dim numericalPartX As String = x.Substring(0, indexOfSpaceX)
Dim indexOfSpaceY As Integer = y.IndexOf(" "C)
Dim numericalPartY As String = y.Substring(0, indexOfSpaceY)
Dim numberX As Integer
Dim numberY As Integer
If Not Integer.TryParse(numericalPartX, numberX) OrElse Not Integer.TryParse(numericalPartY, numberY) Then
'Some code to handle the case where number is missing
Throw New ArgumentException()
End If
If numberX <> numberY Then
Return numberX - numberY
End If
Dim textPartX As String = x.Substring(indexOfSpaceX + 1)
Dim textPartY As String = x.Substring(indexOfSpaceY + 1)
Return [String].Compare(textPartX, textPartY, True, CultureInfo.CurrentCulture)
End Function
End Class
Public Class Person
Public Property Value() As String
Get
Return m_Value
End Get
Set
m_Value = Value
End Set
End Property
Private m_Value As String
Public Sub New(value__1 As String)
Value = value__1
End Sub
End Class
Class Program
Private Shared Sub Main(args As String())
Dim sortme As New List(Of Person)(New () {New Person("1001 street name"), New Person("103 street name"), New Person("1021 street name")})
Dim result = sortme.OrderBy(Function(p) p.Value, New StreetComparer())
For Each person As var In result
Console.WriteLine(person.Value)
Next
Console.ReadKey()
End Sub
End Class