1

我已经实现了一个UISearchDisplayController允许用户搜索表的方法。目前我用来搜索的谓词如下,

NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:@"Name contains[cd] %@", searchText];

现在假设用户搜索“beans,cooked”,在表中找到相应的匹配项。但是,如果用户在搜索文本中输入“beans cooked”而不使用逗号,则不会找到匹配项。

如何在搜索时重新编写谓词以“忽略”逗号?换句话说,我怎样才能重写它,以便它认为“beans,cooked”等于“beanswritten”(没有逗号)?

4

3 回答 3

2

首先是免责声明:

我认为您要做的是为您的搜索算法添加一些“模糊性”,看到您想让您的匹配对用户输入的某些差异不敏感。

谓词(它们是逻辑结构)本质上并不模糊,因此问题和所选工具之间存在潜在的阻抗不匹配。

无论如何,解决它的一种方法可能是向您的模型对象类添加一个方法。

在这种方法中,您可以清理您的姓名字符串,使其仅包含最基本的字符,例如数字、ascii 字母和空格。

由于完全确定性,这样的方法实际上是对象上的只读字符串属性,因此它可用于匹配谓词。

这是一个删除标点符号、重音符号和变音符号的实现:

- (NSString *)simplifiedName
{
    // First convert the name string to a pure ASCII string
    NSData *asciiData = [self.name dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];

    NSString *asciiString = [[[NSString alloc] initWithData:asciiData encoding:NSASCIIStringEncoding] lowercaseString];

    // Define the characters that we will allow in our simplified name
    NSString *searchCharacters = @"0123456789 abcdefghijklmnopqrstuvwxyz";

    // Remove anything else
    NSString *regExPattern = [NSString stringWithFormat:@"[^%@]", searchCharacters];

    NSString *simplifiedName = [asciiString stringByReplacingOccurrencesOfString:regExPattern withString:@"" options:NSRegularExpressionSearch range:NSMakeRange(0, asciiString.length)];

    return simplifiedName;
}

现在,可以进行谓词以在简化名称中进行搜索:

NSPredicate *pred = [NSPredicate predicateWithFormat:@"self.simplifiedName = %@", searchString];

您当然希望使用用于清除名称的相同算法清除搜索字符串,因此将其分解为可在两个地方使用的通用方法可能是个好主意。

最后,simplifiedName还可以通过在模型对象类中实现一个类别来添加该方法,这样您就不必修改其代码,如果您的对象类是在 Core Data 自动生成的文件中定义的,这很方便。

于 2012-06-17T14:22:45.783 回答
1

这可能有点 hacky,但您可以从搜索词中删除逗号。

例子:

searchText = [searchText stringByReplacingOccurrencesOfString:@"," withString:@""];
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:@"Name contains[cd] %@", searchText];
于 2012-06-15T22:34:33.903 回答
0

我为此类问题找到的最佳解决方案是在每个项目字典中添加一个具有相同名称但所有标点符号、逗号、破折号等的条目,就像在这个答案中一样

于 2012-06-16T17:45:05.713 回答