簡體   English   中英

在vb.net中對類數組進行排序

[英]To sort a class array in vb.net

我花了兩天的時間在互聯網上搜索,試圖找到解決方案來簡單地排序一個由一類字符串和整數組成的數組(只有一個可能包含不規則字符的字符串元素)。 請幫忙! 我已經基於microsoft示例創建了一個簡化的代碼,我想要做的是:

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

如果你想按Make屬性排序,一個開箱即用的方法是使用Array.SortComparison(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方法

另一個挑剔,遵循.NET命名/ 大寫慣例 ,使用Car而不是car

Linq是你的朋友和OrderBy方法。 但是為了使用你的數組需要成為List

您可以輕松地將其轉換為List並按照這樣的make對其進行排序(不是這不會對原始列表進行排序,而是創建按您指定的條件排序的新列表):

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)

您可以為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類。 這將允許您提出簡潔的語法,例如:

Array.Sort(arrayOfCars, New KeyComparer(Function(c As car) c.Make))

Array.Sort(..., Comparison)方法的缺點是它不處理空值,並且如果任何列表元素碰巧為null,則會拋出NullReferenceException 這可能與您的案件有關,也可能與您的案件無關。

在線有很多KeyComparer實現。 我在KeyComparer文章中詳細討論了這個具體問題 - 並提供了一個示例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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM