And*_*ena 3 .net c# string string-comparison
我的代码是这样的:
public class CaseAccentInsensitiveEqualityComparer : IEqualityComparer<string>
{
public bool Equals(string x, string y)
{
return string.Compare(x, y, CultureInfo.InvariantCulture, CompareOptions.IgnoreNonSpace | CompareOptions.IgnoreCase) == 0;
}
public int GetHashCode(string obj)
{
// not sure what to put here
}
}
Run Code Online (Sandbox Code Playgroud)
我知道的作用,GetHashCode在这方面,有什么我缺少的是如何产生的InvariantCulture,IgnoreNonSpace以及IgnoreCase版本obj,这样我可以回到它的HashCode。
我可以从obj自己身上删除变音符号和案件,然后返回hashcode,但我想知道是否有更好的选择。
小智 5
在内部返回0 GetHashCode()(如@Michael Perrenoud指出的那样)是因为Dictionaries和HashMaps调用Equals(),即使GetHashCode()两个对象返回相同的值。
该规则是,GetHashCode()方法,如果对象是相等的,必须返回相同的值。
缺点是HashSet(或Dictionary)性能下降到与使用List相同的程度。要找到一个项目,它必须调用Equals()每个比较。
一种更快的方法是将其转换为Accent Insensitive字符串并获取其哈希码。
从这篇文章中删除重音符号的代码
static string RemoveDiacritics(string text)
{
return string.Concat(
text.Normalize(NormalizationForm.FormD)
.Where(ch => CharUnicodeInfo.GetUnicodeCategory(ch) !=
UnicodeCategory.NonSpacingMark)
).Normalize(NormalizationForm.FormC);
}
Run Code Online (Sandbox Code Playgroud)
比较器代码:
public class CaseAccentInsensitiveEqualityComparer : IEqualityComparer<string>
{
public bool Equals(string x, string y)
{
return string.Compare(x, y, CultureInfo.InvariantCulture, CompareOptions.IgnoreNonSpace | CompareOptions.IgnoreCase) == 0;
}
public int GetHashCode(string obj)
{
return obj != null ? RemoveDiacritics(obj).ToUpperInvariant().GetHashCode() : 0;
}
private string RemoveDiacritics(string text)
{
return string.Concat(
text.Normalize(NormalizationForm.FormD)
.Where(ch => CharUnicodeInfo.GetUnicodeCategory(ch) !=
UnicodeCategory.NonSpacingMark)
).Normalize(NormalizationForm.FormC);
}
}
Run Code Online (Sandbox Code Playgroud)