对 vb.net 中的 class 数组进行排序
To sort a class array in vb.net
我花了 2 天时间在互联网上搜索,试图找到解决方案来简单地对由 class 字符串和整数组成的数组进行排序(仅按可能包含不规则字符的字符串元素中的 1 个) .请帮忙!我已经根据微软的例子创建了一个我想做的简化代码:
Public Class Form1
Class car
Public Make As String = ""
Public Year As Integer = 0
End Class
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim arrayOfCars() As car
Dim arrayElement As Integer = 0
'Exploded simplified loop to fill the array (original has 20 objects in the class
'and the array grows depending on input to no more than a few hundred.
ReDim arrayOfCars(0)
arrayOfCars(0) = New car
arrayOfCars(0).Make = "Ford"
arrayOfCars(0).Year = 1992
ReDim Preserve arrayOfCars(1)
arrayOfCars(1) = New car
arrayOfCars(1).Make = "Fiat"
arrayOfCars(1).Year = 1988
ReDim Preserve arrayOfCars(2)
arrayOfCars(2) = New car
arrayOfCars(2).Make = "Buick"
arrayOfCars(2).Year = 1932
ReDim Preserve arrayOfCars(3)
arrayOfCars(3) = New car
arrayOfCars(3).Make = "Ford"
arrayOfCars(3).Year = 1932
ReDim Preserve arrayOfCars(4)
arrayOfCars(4) = New car
arrayOfCars(4).Make = "Dodge"
arrayOfCars(4).Year = 1999
ReDim Preserve arrayOfCars(5)
arrayOfCars(5) = New car
arrayOfCars(5).Make = "Honda"
arrayOfCars(5).Year = 1977
'view array before sort
For i = 0 To 5
Debug.WriteLine(arrayOfCars(i).Make & vbTab & arrayOfCars(i).Year)
Next
Debug.WriteLine("*************************")
'sort array by the string component [Make]
'Array.Sort(arrayOfCars)
'arrayOfCars = arrayOfCars.OrderBy(Function(car) car.Make)
'????????????????
'view array after sort
For i = 0 To 5
Debug.WriteLine(arrayOfCars(i).Make & vbTab & arrayOfCars(i).Year)
Next
End Sub
End Class
Linq 是您的朋友,也是 OrderBy
方法。但是为了使用它,你的数组需要是 List
.
您可以轻松地将其转换为列表并按如下方式对其进行排序(并不是说这不会对原始列表进行排序,它会创建一个按您指定的条件排序的新列表):
Dim sortedListOfCars = arrayOfCars.ToList.OrderBy(Function(x) x.Make)
但将其声明为列表会更容易:
Dim listOfCars As New List(Of Car)
然后像这样添加你的车
listOfCars.Add(New Car With {.Make = "Ford", .Year = 1992})
listOfCars.Add(New Car With {.Make = "Fiat", .Year = 1988})
'etc.
那你就直接OrderBy:
Dim sortedListOfCars = arrayOfCars.OrderBy(Function(x) x.Make)
如果您想按 Make
属性 排序,一种开箱即用的方法是使用 Array.Sort
和 Comparison(Of T)
重载:
Array.Sort(arrayOfCars, Function(car1 As Car, car2 as Car)
Return car1.Make.CompareTo(car2.Make)
End Function)
请注意,您应该注意 Nothing
或(更有可能)Make
值 Nothing
的汽车。两者都会导致 NullReferenceException
。因此你可以使用:
Array.Sort(arrayOfCars, Function(car1 As Car, car2 As Car)
If Object.ReferenceEquals(car1,car2)
return 0
Else if car1 is nothing
Return -1
Else if car2 is nothing
Return 1
Else
return String.Compare(car1.Make, car2.Make)
End If
End Function)
另一种(效率稍低,因为它需要重新创建数组)方法是 LINQ:
Dim orderedCars = from car in arrayOfCars
order by car.Make Ascending
arrayOfCars = arrayOfCars.ToArray()
LINQ 方法更易于维护且更易于阅读,但它需要创建一个新数组。因此,如果您不想修改原始数组,则应该使用它。
一般来说,如果要添加对象,则不应使用数组,因为数组是固定大小的集合。请改用 List(Of Car)
,它有一个 Add
method。
另一个吹毛求疵,遵循.NET命名/capitalization conventions,使用Car
而不是car
。
您可以为 Array.Sort() 函数实现一个 IComparer。
Public Class CarComparer : Implements IComparer
Function Compare(x As car, y As car) As Integer _
Implements IComparer.Compare
Return New CaseInsensitiveComparer().Compare(x.Make, y.Make)
End Function
End Class
这样使用:
Array.Sort(arrayOfCars, new CarComparer())
如果您经常有此要求,则应实施 KeyComparer
class。这将允许您提出简洁的语法,例如:
Array.Sort(arrayOfCars, New KeyComparer(Function(c As car) c.Make))
Array.Sort(..., Comparison)
方法的缺点是它不处理空值,如果您的任何列表元素恰好为空值,则会抛出 NullReferenceException
。这可能与您的情况相关,也可能不相关。
网上有很多 KeyComparer
实现。我已经在我的 KeyComparer
article 中详细讨论了这个具体问题,并提供了一个示例 C# 实现。 VB.NET 转换如下:
Public Class KeyComparer(Of TSource, TKey)
Inherits Comparer(Of TSource)
Private ReadOnly _keySelector As Func(Of TSource, TKey)
Private ReadOnly _innerComparer As IComparer(Of TKey)
Public Sub New(keySelector As Func(Of TSource, TKey), Optional innerComparer As IComparer(Of TKey) = Nothing)
_keySelector = keySelector
_innerComparer = If(innerComparer, Comparer(Of TKey).[Default])
End Sub
Public Overrides Function Compare(x As TSource, y As TSource) As Integer
If Object.ReferenceEquals(x, y) Then
Return 0
End If
If x Is Nothing Then
Return -1
End If
If y Is Nothing Then
Return 1
End If
Dim xKey As TKey = _keySelector(x)
Dim yKey As TKey = _keySelector(y)
Return _innerComparer.Compare(xKey, yKey)
End Function
End Class
我花了 2 天时间在互联网上搜索,试图找到解决方案来简单地对由 class 字符串和整数组成的数组进行排序(仅按可能包含不规则字符的字符串元素中的 1 个) .请帮忙!我已经根据微软的例子创建了一个我想做的简化代码:
Public Class Form1
Class car
Public Make As String = ""
Public Year As Integer = 0
End Class
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim arrayOfCars() As car
Dim arrayElement As Integer = 0
'Exploded simplified loop to fill the array (original has 20 objects in the class
'and the array grows depending on input to no more than a few hundred.
ReDim arrayOfCars(0)
arrayOfCars(0) = New car
arrayOfCars(0).Make = "Ford"
arrayOfCars(0).Year = 1992
ReDim Preserve arrayOfCars(1)
arrayOfCars(1) = New car
arrayOfCars(1).Make = "Fiat"
arrayOfCars(1).Year = 1988
ReDim Preserve arrayOfCars(2)
arrayOfCars(2) = New car
arrayOfCars(2).Make = "Buick"
arrayOfCars(2).Year = 1932
ReDim Preserve arrayOfCars(3)
arrayOfCars(3) = New car
arrayOfCars(3).Make = "Ford"
arrayOfCars(3).Year = 1932
ReDim Preserve arrayOfCars(4)
arrayOfCars(4) = New car
arrayOfCars(4).Make = "Dodge"
arrayOfCars(4).Year = 1999
ReDim Preserve arrayOfCars(5)
arrayOfCars(5) = New car
arrayOfCars(5).Make = "Honda"
arrayOfCars(5).Year = 1977
'view array before sort
For i = 0 To 5
Debug.WriteLine(arrayOfCars(i).Make & vbTab & arrayOfCars(i).Year)
Next
Debug.WriteLine("*************************")
'sort array by the string component [Make]
'Array.Sort(arrayOfCars)
'arrayOfCars = arrayOfCars.OrderBy(Function(car) car.Make)
'????????????????
'view array after sort
For i = 0 To 5
Debug.WriteLine(arrayOfCars(i).Make & vbTab & arrayOfCars(i).Year)
Next
End Sub
End Class
Linq 是您的朋友,也是 OrderBy
方法。但是为了使用它,你的数组需要是 List
.
您可以轻松地将其转换为列表并按如下方式对其进行排序(并不是说这不会对原始列表进行排序,它会创建一个按您指定的条件排序的新列表):
Dim sortedListOfCars = arrayOfCars.ToList.OrderBy(Function(x) x.Make)
但将其声明为列表会更容易:
Dim listOfCars As New List(Of Car)
然后像这样添加你的车
listOfCars.Add(New Car With {.Make = "Ford", .Year = 1992})
listOfCars.Add(New Car With {.Make = "Fiat", .Year = 1988})
'etc.
那你就直接OrderBy:
Dim sortedListOfCars = arrayOfCars.OrderBy(Function(x) x.Make)
如果您想按 Make
属性 排序,一种开箱即用的方法是使用 Array.Sort
和 Comparison(Of T)
重载:
Array.Sort(arrayOfCars, Function(car1 As Car, car2 as Car)
Return car1.Make.CompareTo(car2.Make)
End Function)
请注意,您应该注意 Nothing
或(更有可能)Make
值 Nothing
的汽车。两者都会导致 NullReferenceException
。因此你可以使用:
Array.Sort(arrayOfCars, Function(car1 As Car, car2 As Car)
If Object.ReferenceEquals(car1,car2)
return 0
Else if car1 is nothing
Return -1
Else if car2 is nothing
Return 1
Else
return String.Compare(car1.Make, car2.Make)
End If
End Function)
另一种(效率稍低,因为它需要重新创建数组)方法是 LINQ:
Dim orderedCars = from car in arrayOfCars
order by car.Make Ascending
arrayOfCars = arrayOfCars.ToArray()
LINQ 方法更易于维护且更易于阅读,但它需要创建一个新数组。因此,如果您不想修改原始数组,则应该使用它。
一般来说,如果要添加对象,则不应使用数组,因为数组是固定大小的集合。请改用 List(Of Car)
,它有一个 Add
method。
另一个吹毛求疵,遵循.NET命名/capitalization conventions,使用Car
而不是car
。
您可以为 Array.Sort() 函数实现一个 IComparer。
Public Class CarComparer : Implements IComparer
Function Compare(x As car, y As car) As Integer _
Implements IComparer.Compare
Return New CaseInsensitiveComparer().Compare(x.Make, y.Make)
End Function
End Class
这样使用:
Array.Sort(arrayOfCars, new CarComparer())
如果您经常有此要求,则应实施 KeyComparer
class。这将允许您提出简洁的语法,例如:
Array.Sort(arrayOfCars, New KeyComparer(Function(c As car) c.Make))
Array.Sort(..., Comparison)
方法的缺点是它不处理空值,如果您的任何列表元素恰好为空值,则会抛出 NullReferenceException
。这可能与您的情况相关,也可能不相关。
网上有很多 KeyComparer
实现。我已经在我的 KeyComparer
article 中详细讨论了这个具体问题,并提供了一个示例 C# 实现。 VB.NET 转换如下:
Public Class KeyComparer(Of TSource, TKey)
Inherits Comparer(Of TSource)
Private ReadOnly _keySelector As Func(Of TSource, TKey)
Private ReadOnly _innerComparer As IComparer(Of TKey)
Public Sub New(keySelector As Func(Of TSource, TKey), Optional innerComparer As IComparer(Of TKey) = Nothing)
_keySelector = keySelector
_innerComparer = If(innerComparer, Comparer(Of TKey).[Default])
End Sub
Public Overrides Function Compare(x As TSource, y As TSource) As Integer
If Object.ReferenceEquals(x, y) Then
Return 0
End If
If x Is Nothing Then
Return -1
End If
If y Is Nothing Then
Return 1
End If
Dim xKey As TKey = _keySelector(x)
Dim yKey As TKey = _keySelector(y)
Return _innerComparer.Compare(xKey, yKey)
End Function
End Class