2016-08-17 180 views
-1

我試圖實現某些答案已經給出的內容。但它在c#,我不知道c#什麼,所以我正在尋找一個vb.net的選擇。按對象屬性排序(對象)列表

我做了一個名爲class其中BomItem有幾個屬性,如數量,種類等

我添加這些​​爲List(of BomItem),但現在我想根據屬性對它們進行排序。如何根據ItemNumber屬性對物品進行分類?

這是link到我找到的c#解決方案。

我的類代碼

Public Class BomItem 
    Public Property ItemNumber As String 
    Public Property Description As String 
    Public Property Quantity As Double 
    Public Property Material As String 
    Public Property Certificate As String 
End Class 

我如何添加BomRow對象

_NewBomList.Add(New BomItem() With { 
        .ItemNumber = oRow.ItemNumber, 
        .Description = oPropSet.Item("Description").Value, 
        .Quantity = oRow.TotalQuantity, 
        .Material = oPropSet.Item("Material").Value, 
        .Certificate = CustomPropertySet.Item("Cert.").Value}) 

的Comparer

Public Class NaturalSort 

Implements IComparer 

Public Function Compare(ByVal x As Object, 
      ByVal y As Object) As Integer Implements IComparer.Compare 

    ' [1] Validate the arguments. 
    Dim s1 As String = x 
    If s1 = Nothing Then 
     Return 0 
    End If 

    Dim s2 As String = y 
    If s2 = Nothing Then 
     Return 0 
    End If 

    Dim len1 As Integer = s1.Length 
    Dim len2 As Integer = s2.Length 
    Dim marker1 As Integer = 0 
    Dim marker2 As Integer = 0 

    ' [2] Loop over both Strings. 
    While marker1 < len1 And marker2 < len2 

     ' [3] Get Chars. 
     Dim ch1 As Char = s1(marker1) 
     Dim ch2 As Char = s2(marker2) 

     Dim space1(len1) As Char 
     Dim loc1 As Integer = 0 
     Dim space2(len2) As Char 
     Dim loc2 As Integer = 0 

     ' [4] Collect digits for String one. 
     Do 
      space1(loc1) = ch1 
      loc1 += 1 
      marker1 += 1 

      If marker1 < len1 Then 
       ch1 = s1(marker1) 
      Else 
       Exit Do 
      End If 
     Loop While Char.IsDigit(ch1) = Char.IsDigit(space1(0)) 

     ' [5] Collect digits for String two. 
     Do 
      space2(loc2) = ch2 
      loc2 += 1 
      marker2 += 1 

      If marker2 < len2 Then 
       ch2 = s2(marker2) 
      Else 
       Exit Do 
      End If 
     Loop While Char.IsDigit(ch2) = Char.IsDigit(space2(0)) 

     ' [6] Convert to Strings. 
     Dim str1 = New String(space1) 
     Dim str2 = New String(space2) 

     ' [7] Parse Strings into Integers. 
     Dim result As Integer 
     If Char.IsDigit(space1(0)) And Char.IsDigit(space2(0)) Then 
      Dim thisNumericChunk = Integer.Parse(str1) 
      Dim thatNumericChunk = Integer.Parse(str2) 
      result = thisNumericChunk.CompareTo(thatNumericChunk) 
     Else 
      result = str1.CompareTo(str2) 
     End If 

     ' [8] Return result if not equal. 
     If Not result = 0 Then 
      Return result 
     End If 
    End While 

    ' [9] Compare lengths. 
    Return len1 - len2 

End Function 

End Class 
+0

如果你需要做一個轉換,然後使用這個網站http://converter.telerik.com/ – FloatingKiwi

回答

3

使用LINQOrderBy

_NewBomList.OrderBy(Function(bi) bi.ItemNumber) 

和下降:

_NewBomList.OrderByDescending(Function(bi) bi.ItemNumber) 

如果你想在你的字符串中的數字順序,你必須把它轉換爲整數第一:

_NewBomList.OrderBy(Function(bi) Integer.Parse(bi.ItemNumber)) 

編輯:
提供爲OrderBy擴展定製IComparer您必須創建一個類來實現IComparer(Of String)其中String是您的ItemNumbers以進行比較:

Class ItemNumberComparer 
    Implements IComparer(Of String) 

    Public Function Compare(String x, String y) 
     Dim ix As String() = x.Split("."C) 
     Dim iy As String() = y.Split("."C) 

     Dim maxLen As Integer = Math.Max(ix.Length, iy.Length) 
     For i As Integer = 0 To maxLen - 2 
      If ix.Length >= i AndAlso iy.Length >= i Then 
       If Integer.Parse(ix(i)) < Integer.Parse(iy(i)) Then 
        Return -1 'If x.i is LT y.i it must be smaller at all 
       ElseIf Integer.Parse(ix(i)) > Integer.Parse(iy(i)) Then 
        Return 1 'If x.i is GT y.i it must be bigger all 
       End If 
      End If 
     Next 
     'This code is only executed if x and y differ at last number or have different ´number of dots 
     If ix.Length = iy.Length Then 
      Return Integer.Parse(ix(ix.Length - 1)).CompareTo(Integer.Parse(iy(iy.Length - 1))) 'Only last number differs 
     Else 
      Return ix.Length.CompareTo(iy.Length) 'The number with more dots is smaller 
     End If 

    End Function  
    End Class 

呼叫語法:

Dim comparer = new ItemNumberComparer() 
_NewBomList.OrderByDescending(Function(bi) bi.ItemNumber, comparer) 
+0

將執行自然排序或通過ascii模型? 1,2,3,4,5,6,7,8,9,10或1,10,2,20,3,30 ...? –

+1

如果您不提供任何自定義IComparer,它將按字母順序排序(1,10,2,20,...) –

+1

如果您希望按文本值按數字排序項目,則必須將「String」值轉換爲數字,例如'_NewBomList.OrderBy(Function(bi)CInt(bi.ItemNumber))'。問題是,如果你的值代表數字,那麼你爲什麼將它們存儲在String屬性中以開始? – jmcilhinney

1

從其他線程此C#代碼:

List<Order> SortedList = objListOrder.OrderBy(o=>o.OrderDate).ToList(); 

相當於此VB代碼:

List(Of Order) SortedList = objListOrder.OrderBy(Function(o) o.OrderDate).ToList() 

正如你所看到的,變化很小。你只需要知道泛型和lambda表達式的語法。

但您應該知道,此代碼不會對您的列表進行排序。它對列表中的項目進行排序,然後按照該順序將它們添加到新列表中。對於許多應用程序來說,這是非常好的,但如果您在其他地方使用同一個列表,那麼您將不會在那裏看到新的訂單。雖然有一些變化,單程實際排序到位名單是這樣的:

objListOrder.Sort(Function(o1, o2) o1.OrderDate.CompareTo(o2.OrderDate)) 
0

另一個解決方案是實現IComparablesee MSDN ref)接口。這個接口被設計在一個自定義的方式你的對象進行排序:

Public Class BomItem 
    Implements IComparable 

    Public Property ItemNumber As String 
    Public Property Description As String 
    Public Property Quantity As Double 
    Public Property Material As String 
    Public Property Certificate As String 

    Public Function CompareTo(obj As Object) As Integer 
     Dim bom = CType(obj, BomItem) 

     If Not bom Is Nothing then 
      Return Me.ItemNumber.CompareTo(bom.ItemNumber) 
     Else 
      Throw New ArgumentException("Object is not a BomItem") 
     End If 
End Class 

,您可以對列表排序是這樣的:

Dim myList As New List(Of BomItem) 

'Code to add your BomItems 

myList.Sort() 

這實際上排序列表,它不會創建一個新的列表。