我正在为字符串实现CaseAccentInsensitiveEqualityComparer.我不确定如何实现GetHashCode
作者:互联网
我的代码是这样的:
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
}
}
我知道GetHashCode在这种情况下的作用,我所缺少的是如何生成obj的InvariantCulture,IgnoreNonSpace和IgnoreCase版本,以便我可以返回它的HashCode.
我可以自己从obj中删除变音符号和大小写,然后返回其哈希码,但是我想知道是否有更好的选择.
解决方法:
在GetHashCode()中返回0是可行的(如@Michael Perrenoud所指出的),因为即使两个对象的GetHashCode()返回相同的值,字典和HashMaps也会调用Equals().
rule是,如果对象相等,则GetHashCode()必须返回相同的值.
缺点是HashSet(或Dictionary)的性能下降到与使用List相同的程度.要查找项目,必须为每个比较调用Equals().
一种更快的方法是将其转换为Accent Insensitive字符串并获取其哈希码.
用于从此post去除重音符号的符号
static string RemoveDiacritics(string text)
{
return string.Concat(
text.Normalize(NormalizationForm.FormD)
.Where(ch => CharUnicodeInfo.GetUnicodeCategory(ch) !=
UnicodeCategory.NonSpacingMark)
).Normalize(NormalizationForm.FormC);
}
比较器代码:
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);
}
}
标签:string-comparison,string,c,net 来源: https://codeday.me/bug/20191031/1978062.html