Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the correct way to compare char ignoring case?

I'm wondering what the correct way to compare two characters ignoring case that will work for all cultures. Also, is Comparer<char>.Default the best way to test two characters without ignoring case? Does this work for surrogate-pairs?

EDIT: Added sample IComparer<char> implementation

If this helps anyone this is what I've decided to use

public class CaseInsensitiveCharComparer : IComparer<char> {     private readonly System.Globalization.CultureInfo ci;     public CaseInsensitiveCharComparer(System.Globalization.CultureInfo ci) {         this.ci = ci;     }     public CaseInsensitiveCharComparer()         : this(System.Globalization.CultureInfo.CurrentCulture) { }     public int Compare(char x, char y) {         return Char.ToUpper(x, ci) - Char.ToUpper(y, ci);     } }  // Prints 3 Console.WriteLine("This is a test".CountChars('t', new CaseInsensitiveCharComparer())); 
like image 345
Brett Ryan Avatar asked Sep 08 '09 16:09

Brett Ryan


People also ask

How do you compare characters when ignoring a case?

Use toLowerCase and toUpperCase to Ignore Character Case in Java. The toLowerCase and toUpperCase convert the characters from upper case to lower case and lower case to upper case. These two methods can be used to compare two characters while ignoring the case.

Is there a way to compare two strings that ignores case?

Java String equalsIgnoreCase() Method This method returns true if the strings are equal, and false if not. Tip: Use the compareToIgnoreCase() method to compare two strings lexicographically, ignoring case differences.

Can I use == to compare char?

Yes, char is just like any other primitive type, you can just compare them by == .


2 Answers

It depends on what you mean by "work for all cultures". Would you want "i" and "I" to be equal even in Turkey?

You could use:

bool equal = char.ToUpperInvariant(x) == char.ToUpperInvariant(y); 

... but I'm not sure whether that "works" according to all cultures by your understanding of "works".

Of course you could convert both characters to strings and then perform whatever comparison you want on the strings. Somewhat less efficient, but it does give you all the range of comparisons available in the framework:

bool equal = x.ToString().Equals(y.ToString(),                                   StringComparison.InvariantCultureIgnoreCase); 

For surrogate pairs, a Comparer<char> isn't going to be feasible anyway, because you don't have a single char. You could create a Comparer<int> though.

like image 117
Jon Skeet Avatar answered Sep 25 '22 00:09

Jon Skeet


As I understand it, there isn't really a way that will "work for all cultures". Either you want to compare characters for some kind of internal, non-displayed-to-the-user reason (in which case you should use the InvariantCulture), or you want to use the CurrentCulture of the user. Obviously, using the user's current culture will mean that you will get different results in different locales, but they will be consistent with what your users in those locales will expect.

Without knowing more about WHY you are comparing two characters, I can't really advise you on which one you should be using.

like image 37
Jon Grant Avatar answered Sep 22 '22 00:09

Jon Grant