2015-11-06 61 views
-1

我想使用排序列表,但它似乎没有按照我想排序的方式排序。我有一个列表字符串值。vb.net排序列表排序顺序不正确

2 
4 
7 
1 
3 
5 
6 
8 
9 
10 

当添加这些值代入我的排序列表中它的返回:

1 
10 
2 
3 
4 
5 
6 
7 
8 
9 

我知道这是因为我这种情况的发生梳理串号码,但你怎么能避免这种情况?

为什么这些值作为字符串输入?分号码 可能有1.1; 1.2; 1.3 ..所以字符串类型必须保留,我不能转换为双打,因为1,1 & 1,10会给我一个错误是相同的值。

如何排序这些值是在9之后而不是1之后?

地址:代码项目添加到列表中

oBOMList.Add(oItemNumber, oIndex) 
+1

请告诉我们您正在使用填充和排序列表中的代码。这可能会帮助我们发现铸造,排序等任何错误。谢谢:) – simonalexander2005

+0

你是在名为[自然分类](http://blog.codinghorror.com/sorting-for-humans-natural-sort-订单/) – Steve

回答

0

我发现这个在互联网上,这要归功于我能够创造的评论像以前一样更好的搜索谢谢大家!

公共类AlphanumComparator 实现的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 
1

你需要写的IComparer(Of T)一个自定义实现来处理字符串进行排序,你想要的方式。然后,您可以告诉您的排序列表使用此比较器对列表中的项目进行排序。比较器将基本上教你的清单如何确定一个项目是高于还是低于列表中的另一个项目。你可以用它来创建你需要的任何一种疯狂的排序行为。

  • 您可以找到文档和示例here
  • 有一个 实施自然排序作为IComparer在答案 到this问题之一。
+0

我并不擅长这些事情,但我检查了代码的演示,并且效果很好。现在我只需要将它放入.net而不是C#中。谢谢回复 – JefE

0

我用下面的扩展方法做一个字母排序列表(从C#迅速转化)上:

''' <summary> 
''' Used to order the given array alphanumerically 
''' </summary> 
''' <typeparam name="T">the type</typeparam> 
''' <param name="source">the source object</param> 
''' <param name="selector">the item being used as the selector</param> 
''' <returns>the sorted list</returns> 
<System.Runtime.CompilerServices.Extension> 
Public Function OrderByAlphanumeric(Of T)(source As IEnumerable(Of T), selector As Func(Of T, [String])) As IEnumerable(Of T) 
    Try 
     Dim max As Int32 
     Try 
      max = source.SelectMany(Of Int32)(Function(i) Regex.Matches(selector(i), "\d+").Cast(Of Match)().Select(Of Int32)(Function(m) m.Value.Length)).Max() 
     Catch ex As Exception 
      max = 0 
     End Try 

     Return source.OrderBy(Function(i) Regex.Replace(selector(i), "\d+", Function(m) m.Value.PadLeft(max, "0"c))) 
    Catch exMain As Exception 
     Return source 
    End Try 
End Function