![](/img/trans.png)
[英]Sort a list of custom objects multiple times by different object properties in 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()
注意:如果按字符以外的其他方式進行排序,則需要創建對象的適當數組/列表以進行比較。
如果可以選擇使用Enum
和Tuple
則容易一些:
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.