Tutorial :.net - Problems with Array.Sort and Array.BinarySearch - culture and globalization


I need to sort an array containing a list of words and search the same using binarysearch. For certain reasons, the word-list must always be sorted using the sorting-rules of "en-US" i.e. American Regional Settings. The code will run under various international Operating Systems and of course this will mean that the word-list will be sorted differently according to the local Regional Settings in use. One problem could arise on a computer/device running with Lithuanian Regional Settings. Why? Because the letter "Y" in most languages is sorted like X-Y-Z while in Lithuanian, the sort order is I-Y-J. This behavior would create havoc to my program.

On a desktop-PC, I could change momentarily the Regional Settings into American English by using:

Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-US")

however since I am developing for Windows Mobile (CF.NET), this piece of code is not possible to implement.

I found some hacks which could let me change the Regional Settings on the device programatically but they are not "official" and considered risky so I prefer avoiding these.

So my question is: how can I force Array.Sort and Array.BinarySearch to use CultureInfo = "en-US" while sorting and searching regardless of the Regional Settings set on the device?

I believe I could use:

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

and implement Comparer to take into consideration CultureInfo (and set it to "en-US") but I don't know how to do that despite trying hard. If anyone could post some sample-code in VB.Net or C# or an explanation how to do it, I would be very grateful.

If you are aware about any alternative solution which works in CF.Net, then of course I am all ears.



I will consider Twanfosson's answer as the accepted solution since my question clearly stated that I wanted to maintain an association with the English language.

However, in means of flexibility I believe Guffa's answer is the best one. Why? Let's use another example: In German, the letter Ö is sorted Ö-X-Z while in Swedish and Finnish, the order is X-Z-Ö. In Estonian the sort order is Z-Ö-X. Complicated, isn't it? Guffa's solution will let me force Swedish sorting-oder (changing CultureInfo) on a device running under German Regional settings. Using Comparer.DefaultInvariant with its association to English wouldn't help in this case, probably the letter Ö would end up with O. Therefore my vote will go to Guffa.


Is it not possible to use the Invariant culture?

InvariantCulture retrieves an instance of the invariant culture. It is associated with the English language but not with any country/region.

Using the invariant culture would make this trivial.

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


Well, the answer to both is to implement a comparer. Create a class that implements the IComprarer(Of String) interface and has it's own CultureInfo object that it uses to compare the strings:

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  

Now you can use it to sort the strings:

Array.Sort(theArray, New StringComparerEnUs())  

and to find them:

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

(The class can of course be made a bit more general by accepting a culture string in the constructor, and you can also add a variable to make use of the ignorecase parameter in the String.Compare call.)


Try this:

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);    }  }  

Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Next Post »