2

我有一个字符串字段,我知道用户稍后会想要搜索它。受 WWDC 2012 Core Data Best Practices session 的启发,我计划将字符串的规范化版本存储到一个单独的字段中,以便优化我的搜索谓词。

我主要关心的是不区分大小写,但是当我规范化字符串时,我认为我也应该规范化 unicode 表示。但我想确保我使用了正确的规范化形式(即 C、D、KC 或 KD)。我是否先转换为小写有关系吗?(本地化不是我的强项。)

所以:

  1. 调用 NSString 的搜索规范化的正确方法是什么?
  2. 确保存储标准化版本的最佳方法是什么。

我将发布我的第一次尝试作为答案,但我很想听听我错在哪里、其他建议或改进。(不幸的是,虽然他们在该视频中显示了搜索谓词,但我认为他们没有显示会话中的代码。)

4

2 回答 2

2

对于您描述的用例,您选择预组合还是分解(C 或 D;虽然使用预组合会节省一点空间)并不重要,但请仔细考虑您是否需要规范或兼容性(K 形式)。TR15有一个很好的图来总结差异(图 6):

也就是说:如果有人搜索“ſ”(a ' long s '),您是否要匹配“s”(反之亦然)?这些被视为“格式区别”,因此您不应将用户输入的文本替换为这些表单(因为您会丢失数据),但您可能希望在搜索时忽略它们。

对于不区分大小写的比较,仅将两个字符串都设为小写并进行比较是不够的。它适用于英语,但有些语言的小写和大写之间的映射(如果甚至存在这种区别)并不那么清楚。W3C wiki对这些“案例折叠”问题进行了很好的总结。不幸的是,您无法通过将数据保存在一个“案例”中来优化存储中的这一点,只有在您知道字符串和语言环境时才能进行适当的比较。

幸运的是,当使用NSString它时,它-compare:options:range:locale:可以让您指定一个NSCaseInsensitiveSearch选项和语言环境(如果您知道的话),它将为您处理这些案例折叠问题(也请查看NSDiacriticInsensitiveSearchNSWidthInsensitiveSearch了解您是否也想了解这些差异)。

于 2013-05-25T01:32:24.490 回答
0

我目前计划做的是覆盖该字段的设置器,如下所示:

- (void)setName:(NSString *)value
{
    [self willChangeValueForKey:@"name"];
    [self setPrimitiveValue:value forKey:@"name"];
    [self didChangeValueForKey:@"name"];

    //Store normalized for for searching
    [self willChangeValueForKey:@"searchName"];
    [self setPrimitiveValue:[[value lowercaseStringWithLocale:[NSLocale currentLocale]] decomposedStringWithCompatibilityMapping] forKey:@"searchName"];
    [self didChangeValueForKey:@"searchName"];
}

我还将 searchName 属性设为只读。

于 2013-05-24T18:44:42.293 回答