簡體   English   中英

vb.net按自定義順序對對象進行排序

[英]vb.net sort list of objects with custom order

我有一個對象列表,我正在嘗試按兩個屬性排序,其中一個屬性按自定義順序排序。 該列表具有ReqType和PartNumber的屬性。 ReqType將為“ M”,“ B”,“ S”或null,我想按該順序對列表進行排序。 然后按PartNumber排序。

Input list:
PartNumber    ReqType
124           B
125           M
123           B
121           S
120           M
115            

Expected Sort:
PartNumber    ReqType
120           M
125           M
123           B
124           B
121           S
115            

我從下面的代碼開始,但這僅按字母順序對ReqType進行排序。

Return EBom.OrderBy(Function(f) f.ReqType).ThenBy(Function(f) f.PartNumber).ToList 

然后,我找到了一種使用下面的代碼創建自定義排序順序的方法。 盡管使用Ebom.Sort()似乎不允許我對PartNumber進行第二排序。 我意識到我可能可以將PartNumber排序添加到自定義函數中,但這似乎需要大量工作。

EBom.Sort()
Return EBom.ToList


Implements IComparable(Of EBomList)
Public Function SortReq(other As EBomList) As Integer Implements IComparable(Of EBomList).CompareTo
    If (Me.ReqType = other.ReqType) Then
        Return 0
    ElseIf (Me.ReqType = "M") Then
        Return -1
    ElseIf (Me.ReqType = "B") Then
        If (other.ReqType = "M") Then
            Return 1
        Else
            Return -1
        End If
    ElseIf (Me.ReqType = "S") Then
        If (other.ReqType = "M" Or other.ReqType = "B") Then
            Return 1
        Else
            Return -1
        End If
    Else
        Return 1
    End If
End Function

是否有一種更簡單的方法來按自定義順序排序,或者至少將自定義排序功能與.thenby(.....)組合以獲得我想要的順序?

這樣做的更干凈的代碼版本是在類似於下面的sort方法中使用Function。

    d.Sort(Function(X As EBomList, Y As EBomList)
               Dim Tx As Integer = InStr("MBS ", X.ReqType.PadLeft(1, " "c))
               Dim Ty As Integer = InStr("MBS ", Y.ReqType.PadLeft(1, " "c))
               Select Case Tx
                   Case Is < Ty : Return -1
                   Case Is > Ty : Return 1
                   Case Else : Return X.PartNumber.CompareTo(Y.PartNumber)
               End Select
           End Function)

注意,僅在類型代碼相同時才需要檢查零件號。

我假設您的部件號實際上是一個數字。 如果是字符串,則需要適當地填充它。 例如。

Return X.PartNumber.PadLeft(6," "c).CompareTo(Y.PartNumber.PadLeft(6," "c))

替代和更快的方法

如果您有大量數據,則可能需要考慮擴大EBomLit來創建排序鍵,而不是進行字符串搜索...

如...

Private _ReqType As String
Private _TypeKey As Integer 

Public Property ReqType As String
    Get
        Return _ReqType
    End Get
    Set(value As String)
        _ReqType = value
        _TypeKey = InStr("MBS ", value.PadLeft(1, " "c))
    End Set
End Property

Public ReadOnly Property TypeKey As Integer
    Get
        Return _TypeKey
    End Get
End Property

然后排序變成...

    d.Sort(Function(X As EBomList, Y As EBomList)
               Select Case X.TypeKey
                   Case Is < Y.TypeKey : Return -1
                   Case Is > Y.TypeKey : Return 1
                   Case Else : Return X.PartNumber.CompareTo(Y.PartNumber)
               End Select
           End Function)

更快的靜止

您甚至可以通過在帶有填充的“ PartNumber”的“ TypeKey”之外創建完整排序鍵,並將其用作鍵來將整個shebang保存在SortedDictionary中而不是List中,來進一步擴展該鍵。

只需創建一個ReqTypes列表並查找索引:

Dim sortOrder = "MBS "

Dim sortedList = List.OrderBy(Function(x) sortOrder.IndexOf(If(x.ReqType Is Nothing, " ", x.ReqType))).ThenBy(Function(x) x.PartNumber).ToList()

注意:如果按字符以外的其他方式進行排序,則需要創建對象的適當數組/列表以進行比較。

如果可以選擇使用EnumTuple則容易一些:

Enum PartNumber As Byte : M : B : S : __ : End Enum

Dim list = New List(Of Tuple(Of PartNumber, Integer)) From {
    Tuple.Create(PartNumber.B, 124),
    Tuple.Create(PartNumber.M, 125),
    Tuple.Create(PartNumber.B, 123),
    Tuple.Create(PartNumber.S, 121),
    Tuple.Create(PartNumber.M, 120),
    Tuple.Create(PartNumber.__, 115)}

list.Sort()

For Each item In list
    Debug.Print(item.Item2 & vbTab & item.Item1.ToString.Replace("_", ""))
Next

輸出:

120 M
125 M
123 B
124 B
121 S
115 

暫無
暫無

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

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