【发布时间】:2021-06-16 07:05:49
【问题描述】:
在我的应用程序的一部分中,我有一个选项可以显示当前艺术家不在音乐库中的专辑列表。为此,我调用了一个音乐 API 来获取该艺术家的所有专辑列表,然后删除当前库中的专辑。
为了应对名称的不同大小写以及标题中可能缺少(或额外的标点符号)的问题,我写了一个IEqualityComparer 以在.Except 调用中使用:
var missingAlbums = allAbumns.Except(ownedAlbums, new NameComparer());
这是Equals 方法:
public bool Equals(string x, string y)
{
// Check whether the compared objects reference the same data.
if (ReferenceEquals(x, y)) return true;
// Check whether any of the compared objects is null.
if (x is null || y is null)
return false;
return string.Compare(x, y, CultureInfo.CurrentCulture, CompareOptions.IgnoreCase | CompareOptions.IgnoreSymbols) == 0;
}
这是GetHashCode 方法:
public int GetHashCode(string obj)
{
// Check whether the object is null
if (obj is null) return 0;
// Make lower case. How do I strip symbols?
return obj.ToLower().GetHashCode();
}
当然,当字符串包含符号时,这会失败,因为我在获取哈希码之前没有删除它们,所以两个字符串(例如“Baa,baa,blacksheep”和“Baa baa Blacksheep”)仍然存在即使转换为小写也不等于。
我已经编写了一个去除符号的方法,但这意味着我必须猜测这些符号实际上是什么。它适用于我迄今为止尝试过的案例,但我预计它最终会失败。我想要一种更可靠的删除符号的方法。
鉴于CompareOptions.IgnoreSymbols 存在,我可以调用一种方法来从字符串中删除这些字符吗?或者失败了,一个将返回所有符号的方法?
我找到了用于字符的IsPunctuation 方法,但我无法确定它认为的标点符号是否与字符串比较选项认为的符号相同。
【问题讨论】:
-
要删除字符串的所有符号吗?只保留字母?最终数字也允许Element3?还是只保留逗号和分号等特定字符,例如 Simon & Garfunkel?
-
@OlivierRogier 我需要删除在
string.Compare上使用CompareOptions.IgnoreSymbols标志时被忽略的所有符号。GetHashCode必须为两个被比较视为相同的字符串返回相同的值。 -
相关:Can I obtain the result string used for comparisons with CompareOptions? 那里有一些好的(被低估的)答案。 Konrad's 基本上是我首先想到的:“我敢打赌,API 正在调用您可以直接调用的本机 Win32 API。让其他人来跟踪什么是标点符号和不是标点符号。”也许最好的答案是使用
NORM_IGNORESYMBOLS标志 P/InvokeLCMapStringEx(如果尚未包装)。 -
哇,这个问题及其答案和 cmets 周围有很多钻石和代表。
-
@Flydog57:只是去表演一下,我们这些新手仍然可以教老狗一些新技巧。 ;)
标签: c# string iequalitycomparer