0

它没有正确排序这个简单的字符串,我测试它在 Microsoft Framework 3.5、4.0、4.5 和 4.5.1 RC 中发生...

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    Dim strarray() As String = New String() _
        {"a-n|o1|2004/02/12|", _
         "an|n9|2004/02/09|", _
         "an|o2|2003/12/30|"}
    Array.Sort(strarray)
    Debug.Print(String.Join(vbNewLine, strarray))
End Sub

输出是:

an|n9|2004/02/09|
a-n|o1|2004/02/12|
an|o2|2003/12/30|

这是错误的。“an”字符串不应位于其他两个“an”字符串之间。我还验证了无论第一个字母是什么都会发生这种情况......所以你可以用“b”或“t”而不是“a”替换每个字符串的第一个字母,它做同样的事情。但是,如果我从琴弦上剪掉一些末端,比如这个......

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    Dim strarray() As String = New String() _
        {"a-n|", _
         "an|", _
         "an|"}
    Array.Sort(strarray)
    Debug.Print(String.Join(vbNewLine, strarray))
End Sub

然后输出看起来更正确,它给出:

an|
an|
a-n|

有没有更可靠的方法对字符串数组进行排序?Array.Sort 中的这个错误/行为损坏了我的一个数据库。

4

2 回答 2

2

这不是错误。

默认值Comparer(Of String)(但不是默认值EqualityComparer(Of String))使用与文化相关的比较。在不同的文化中可能使用不同的约定。例如,有些文化说 anÖ在 a 之前是P因为某种字母在字母表中O出现在之前P,而其他文化则相反,因为Ö是一个单独的字母,与 无关O,并且Ö在其字母表中出现较晚(在 之后Z)。

请注意,aÖ可以通过两种方式进行 Unicode 标准化,可以是单个System.Char值,也可以是两个Char值(anO后跟一个组合¨)。

同样在某些文化中,在某些情况下,两个字母被视为一个字母。例如,在匈牙利文化 ( "hu-HU") 中,匈牙利语中cukor一个字母,因此在字母表中位于之前。同样,在丹麦语 ( ) 中,由于在此处具有特殊地位,因此出现在前面。 csakcsc"da-DK"odenseaner aalborgenseraa

你的文化是什么?

当涉及连字符-时,就像在您的问题中一样,.NET 中的所有文化在排序时都会忽略此字符,仅在字符串在其他方面相同时才考虑它。这解释了您看到的行为:如果您-从具有一个字符的字符串中删除该字符,您的三个字符串仍然是不同的。它们被排序,就好像-它们不存在一样。

就像我说的,这适用于 .NET 中的所有文化(当前),包括InvariantCulture.

如果您想使用使用每个数值的排序Char,并且没有文化,请使用(就像在对您的问题的评论中建议的那样):

Array.Sort(strarray, StringComparer.Ordinal)
于 2013-09-24T12:45:08.270 回答
1

请参阅http://msdn.microsoft.com/en-us/library/system.globalization.compareoptions.aspx?cs-save-lang=1&cs-lang=vb#code-snippet-1

具体来说,这两行:

  myComp = New MyStringComparer(CompareInfo.GetCompareInfo("en-US"),
             CompareOptions.StringSort)
  Array.Sort(myArr, myComp)

应该向您展示如何获得您期望的排序顺序。

于 2013-09-21T04:59:56.397 回答