【问题标题】:.net - Problems with Array.Sort and Array.BinarySearch - culture and globalization.net - Array.Sort 和 Array.BinarySearch 的问题 - 文化和全球化
【发布时间】:2010-10-20 10:49:33
【问题描述】:

我需要对包含单词列表的数组进行排序并使用二进制搜索进行搜索。由于某些原因,必须始终使用“en-US”的排序规则对单词列表进行排序,即美国区域设置。代码将在各种国际操作系统下运行,当然,这意味着单词列表将根据使用的本地区域设置进行不同的排序。在使用立陶宛区域设置运行的计算机/设备上可能会出现一个问题。为什么?因为字母“Y”在大多数语言中的排序方式为 X-Y-Z,而在立陶宛语中,排序顺序为 I-Y- J。这种行为会对我的程序造成严重破坏。

在台式电脑上,我可以使用以下命令将区域设置暂时更改为美式英语:

Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("zh-CN")

但是,由于我正在为 Windows Mobile (CF.NET) 进行开发,因此无法实现这段代码。

我发现了一些黑客可以让我以编程方式更改设备上的区域设置,但它们不是“官方”并且被认为是有风险的,所以我宁愿避免这些。

所以我的问题是:无论设备上设置的区域设置如何,如何强制 Array.Sort 和 Array.BinarySearch 在排序和搜索时使用 CultureInfo = "en-US"?

我相信我可以使用:

Public Shared Function BinarySearch(Of T) ( _
    array As T(), _
    value As T, _
    comparer As IComparer(Of T) _
) As Integer

并实施 Comparer 以考虑 CultureInfo(并将其设置为“en-US”),但我不知道如何做到这一点,尽管我很努力。如果有人可以在 VB.Net 或 C# 中发布一些示例代码或说明如何操作,我将不胜感激。

如果您知道任何可在 CF.Net 中使用的替代解决方案,那么当然,我会全力以赴。

谢谢。

编辑:

我会将 Twanfosson 的回答视为已接受的解决方案,因为我的问题清楚地表明我想与英语保持联系。

但是,在灵活性方面,我相信 Guffa 的答案是最好的。为什么?让我们再举一个例子:在德语中,字母 Ö 排序为 Ö-X-Z,而在瑞典语和芬兰语中,顺序为 X-Z-Ö。在爱沙尼亚语中,排序顺序是 Z-Ö-X。很复杂,不是吗? Guffa 的解决方案将让我在德国区域设置下运行的设备上强制使用瑞典语排序顺序(更改 CultureInfo)。在这种情况下,使用 Comparer.DefaultInvariant 及其与英语的关联不会有帮助,可能字母 Ö 会以 O 结尾。因此我的投票将投给 Guffa。

【问题讨论】:

    标签: c# .net vb.net windows-mobile compact-framework


    【解决方案1】:

    嗯,两者的答案都是实现一个比较器。创建一个实现IComparer(Of String) 接口的类,并拥有自己的CultureInfo 对象,用于比较字符串:

    Public Class StringComparerEnUs
       Implements IComparer(Of String)
    
       Private _culture As CultureInfo
    
       Public Sub New()
          _culture = New CultureInfo("en-US")
       End Sub
    
       Public Function Compare(ByVal x As String, ByVal y As String)
          Return String.Compate(x, y, false, _culture)
       End Function
    
    End Class
    

    现在您可以使用它对字符串进行排序:

    Array.Sort(theArray, New StringComparerEnUs())
    

    并找到它们:

    pos = BinarySearch(theArray, "Dent, Arthur", new StringComparerEnUs())
    

    (当然,可以通过在构造函数中接受文化字符串使该类更通用,您还可以添加一个变量以在String.Compare 调用中使用ignoreCase 参数。)

    【讨论】:

      【解决方案2】:

      试试这个:

      class EnglishComparer : IComparer<string>
      {
        static CultureInfo __english = new CultureInfo("en-US");
      
        public int Compare(string x, string y)
        {
          return string.Compare(x, y, __english, CompareOptions.None);
        }
      }
      

      【讨论】:

        【解决方案3】:

        不能使用Invariant 文化吗?

        InvariantCulture 检索实例 不变的文化。它是 与英语有关 但不适用于任何国家/地区。

        使用不变的文化将使这变得微不足道。

        Array.Sort( myArray, Comparer.DefaultInvariant );
        
        Array.BinarySearch( myArray, myString, Comparer.DefaultInvariant );
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-08-18
          • 2011-08-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-11-03
          相关资源
          最近更新 更多