Vb.net 如何使用包含数字的字符串对列表进行排序?
我有一个包含地址的Tlist。当我对列表排序时,地址中的数字被视为字符串,并且排序不正确。我应该如何对列表进行升序排序Vb.net 如何使用包含数字的字符串对列表进行排序?,vb.net,linq,list,Vb.net,Linq,List,我有一个包含地址的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)))
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
这个想法是编写你自己的比较器,它首先考虑数字前缀,然后再考虑字符串本身。这个比较器可以在任何地方使用,例如在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());
}
}
公共类街道比较器:IComparer
{
公共整数比较(字符串x、字符串y)
{
int indexOfSpaceX=x.IndexOf(“”);
字符串numericalPartX=x.Substring(0,indexOfSpaceX);
int indexOfSpaceY=y.IndexOf(“”);
字符串numericalPartY=y.Substring(0,indexOfSpaceY);
整数;
整数;
如果(!int.TryParse(numericalPartX,out numberX)||
!int.TryParse(numericalPartY,out numberY))
{
//一些代码用于处理缺少数字的情况
抛出新ArgumentException();
}
如果(numberX!=numberY)
{
返回编号x编号;
}
字符串textPartX=x.Substring(indexOfSpaceX+1);
字符串textPartY=x.Substring(indexOfSpaceY+1);
返回String.Compare(textPartX,textPartY,true,CultureInfo.CurrentCulture);
}
}
班级计划
{
静态void Main(字符串[]参数)
{
var myStreets=new[]{“01 aaa”,“02 bbb”};
var result=myStreets.OrderBy(s=>s,new StreetComparer());
}
}
现在,一个完全适合您的用例的VB.NET版本列出了按属性排序的类:
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
公共类街道比较器
实现(字符串的)IComparer
公共函数比较(x为字符串,y为字符串)为整数
Dim indexOfSpaceX为整数=x.IndexOf(““C”)
Dim numericalPartX As String=x.Substring(0,indexOfSpaceX)
Dim INDEXOFSPACE作为整数=y.IndexOf(““C”)
Dim numericalPartY As String=y.Substring(0,INDEXOFSPACE)
作为整数的Dim numberX
作为整数的Dim数
如果不是Integer.TryParse(numericalPartX,numberX)或lse不是Integer.TryParse(numericalPartY,numberY),则
'一些代码来处理缺少数字的情况
抛出新的ArgumentException()
如果结束
如果是数字那么
返回编号x-编号
如果结束
Dim textPartX As String=x.Substring(indexOfSpaceX+1)
Dim textPartY As String=x.Substring(INDEXOFSPACE+1)
返回[String]。比较(textPartX,textPartY,True,CultureInfo.CurrentCulture)
端函数
末级
公共阶层人士
作为字符串的公共属性值()
得到
返回m_值
结束
设置
m_值=值
端集
端属性
私有m_值作为字符串
Public Sub New(值为字符串)
值=值1
端接头
末级
班级计划
专用共享Sub-Main(参数为字符串())
Dim sortme作为新名单(人员)(新(){新人员(“1001街道名称”)、新人员(“103街道名称”)、新人员(“1021街道名称”))
Dim结果=sortme.OrderBy(函数(p)p.Value,New StreetComparer())
每个人作为结果中的var
Console.WriteLine(person.Value)
下一个
Console.ReadKey()
端接头
末级
请给我们一个3个地址的示例,说明它们是如何排序的,以及您希望它们应该如何排序。当然可以。非常感谢。我刚刚更新了线程来说明这一点。这很好,但不幸的是,我有一个Tlist,它包含一堆类属性。如果我将列表转换为不同的格式,则很难维护数据。这无关紧要。据我所知,你有一个像Person这样的类,有一个财产地址。在这种情况下,您的排序器应该如下所示var result=myTlist.OrderBy(person=>person.Address,new streetcomarer())代码>它将按地址对人员进行排序。最后,您可以调用.ToList()
,如果您对列表更熟悉,它将使排序后的列表再次成为可枚举的列表。根据您的示例调整sortme=sortme.OrderBy(p=>p.Value,new streetcomarer()).AsList()
这将按属性对列表进行排序sortme
。Valie
。