Reputation: 330
I've a question like the link below but much more complicated: Ignoring accented letters in string comparison
I have a dictionary and some values inside like:
{[Ministère de l'économie, 139]}
{[Ministère des finances, 114]}
and for inserting new elements into the dictionary, as the sames codes, I wrote this:
if (!dict.ContainsKey(str))
{ dict.Add(str, Convert.ToDouble(number)); }
But when I want to check the existence of this value : {[Ministère de l'economie, 139]} it returns it doesn't exist.
How can I implement this response to my code?
string.Compare(s1, s2, CultureInfo.CurrentCulture, CompareOptions.IgnoreNonSpace);
On the other way, as the title of my question, how can I overwrite the general (or the main) string comparison method in my application?
Upvotes: 1
Views: 995
Reputation: 111920
Starting from .NET 4.6 there are some interesting overloads of CompareInfo
, so that the first solution suggested in https://stackoverflow.com/a/368850/613130 is usable in an IEqualityComparer<string>
:
public class StringComparerIgnoreDiacritics : IEqualityComparer<string>
{
public static readonly StringComparerIgnoreDiacritics CurrentCulture = new StringComparerIgnoreDiacritics(CultureInfo.CurrentCulture.CompareInfo);
public readonly CompareInfo CompareInfo;
public StringComparerIgnoreDiacritics(CompareInfo compareInfo)
{
CompareInfo = compareInfo;
}
#region IEqualityComparer<string> Members
public bool Equals(string x, string y)
{
return CompareInfo.Compare(x, y, CompareOptions.IgnoreNonSpace) == 0;
}
public int GetHashCode(string obj)
{
return CompareInfo.GetHashCode(obj, CompareOptions.IgnoreNonSpace);
}
#endregion
}
and then
var myDic = new Dictionary<string, int>(var myDic = new Dictionary<string, int>(new IgnoreAccentsAndDiacriticsComparer()).CurrentCulture);
Upvotes: 1
Reputation: 120508
So, combining with the linked answer for removal of accents and diacritics, you can make an IEqualityComparer<string>
to supply to your dictionary:
public class IgnoreAccentsAndDiacriticsComparer:IEqualityComparer<string>
{
public bool Equals(string left, string right)
{
if(left == null && right == null){ return true; }
if(left == null || right == null){ return false; }
return string.Equals(RemoveDiacritics(left), RemoveDiacritics(right));
}
public int GetHashCode(string txt)
{
return RemoveDiacritics(txt).GetHashCode();
}
static string RemoveDiacritics(string text)
{
string formD = text.Normalize(NormalizationForm.FormD);
StringBuilder sb = new StringBuilder();
foreach (char ch in formD)
{
UnicodeCategory uc = CharUnicodeInfo.GetUnicodeCategory(ch);
if (uc != UnicodeCategory.NonSpacingMark)
{
sb.Append(ch);
}
}
return sb.ToString().Normalize(NormalizationForm.FormC);
}
}
Now, construct your dictionary using an instance of this comparer:
var myDic = new Dictionary<string, int>(new IgnoreAccentsAndDiacriticsComparer())
and try adding something accented:
myDic["Aimée"] = 1;
...and read it back out, without the accent:
Console.WriteLine(myDic["Aimee"]); //ŵôõ!
Upvotes: 4