Ios 目标c-按单词搜索
我有一个图书应用程序,用户可以在其中浏览和搜索图书。Ios 目标c-按单词搜索,ios,objective-c,search,nspredicate,Ios,Objective C,Search,Nspredicate,我有一个图书应用程序,用户可以在其中浏览和搜索图书。 例如,以下是书籍列表: “腐肉舒适性” “遮住她的脸” “老人无乡” “猴子的雨衣” 我想实现一种搜索机制,其行为如下: 如果用户搜索“co”,结果将是: “腐肉舒适性” “遮住她的脸” “老无所依” 你可以注意到,我只想找到以“co”开头的单词,这就是为什么《猴子的雨衣》一书虽然包含“co”但没有出现在结果中的原因 为了实现这一点,我创建了一个名为Token的托管对象: Token ------ normalizedString
例如,以下是书籍列表: “腐肉舒适性”
“遮住她的脸”
“老人无乡”
“猴子的雨衣” 我想实现一种搜索机制,其行为如下:
如果用户搜索“co”,结果将是: “腐肉舒适性”
“遮住她的脸”
“老无所依” 你可以注意到,我只想找到以“co”开头的单词,这就是为什么《猴子的雨衣》一书虽然包含“co”但没有出现在结果中的原因 为了实现这一点,我创建了一个名为
Token
的托管对象:
Token
------
normalizedString
我给我的书对象添加了一个多对多的关系
Book
-----
title
releaseDate
tokens (to-many)
现在我的搜索谓词是这样的:
[NSPredicate predicateWithFormat:@"SUBQUERY(tokens, $token, $token.normalizedString BEGINSWITH[cd] %@).@count > 0", [searchString lowercaseString]];
如果我搜索单个单词,这很好,例如,如果我搜索“她”,我会得到结果:“遮住她的脸” 但是当我尝试搜索多个单词时,例如“她的脸”,我没有得到任何结果 我理解为什么会发生这种情况,但在这里找不到正确的解决方案。
任何帮助都将不胜感激我想这是一个黑客解决方案,但我会尝试以不同的方式生成代币。 令牌不是一个单词,而是从一个单词开始,并包含以下文本 因为“遮住她的脸” 而不是
Cover
Her
Face
我会尝试获得代币:
Cover Her Face
Her Face
Face
那么BEGINSWITH解决方案应该按照您的预期工作。这对您有意义吗?假设您将书籍存储在
NSString*
s的nsvariable数组中。。。(对不起,我不知道什么是NSPredicate
。但是如果您能够将书籍转换为NSString*
s,则可以使用此方法)
这可能不是最有效的方法,但它确实有效
除了提供每一种可能的变化之外,必须有一种方法来处理区分大小写的问题,但是我没有时间去弄清楚。可能在比较之前将所有内容都转换为小写?为了回答我自己的问题,我最终标记了搜索字符串,并创建了一个更复杂的谓词来处理这些标记:
- (NSPredicate *)predicateForSearchString:(NSString *)searchString {
NSSet *searchTokens = [[Tokenizer sharedTokenizer] tokenize:searchString];
NSMutableArray *subPreds = [NSMutableArray arrayWithCapacity:searchTokens.count];
for (NSString *token in searchTokens) {
NSPredicate *pred = [NSPredicate predicateWithFormat:@"SUBQUERY(tokens, $token, $token.normalizedString BEGINSWITH[cd] %@).@count > 0", token];
[subPreds addObject:pred];
}
return [NSCompoundPredicate andPredicateWithSubpredicates:[subPreds copy]];
}
你显然想要的是一个KWIK索引。(查一查,应该有几种算法被提出。)在我看来,当你应该用两块石头的时候,你好像在试图用同一块石头打两只鸟。当u用户点击空格时,您不再需要检查前缀,而只需要检查包含?
- (NSPredicate *)predicateForSearchString:(NSString *)searchString {
NSSet *searchTokens = [[Tokenizer sharedTokenizer] tokenize:searchString];
NSMutableArray *subPreds = [NSMutableArray arrayWithCapacity:searchTokens.count];
for (NSString *token in searchTokens) {
NSPredicate *pred = [NSPredicate predicateWithFormat:@"SUBQUERY(tokens, $token, $token.normalizedString BEGINSWITH[cd] %@).@count > 0", token];
[subPreds addObject:pred];
}
return [NSCompoundPredicate andPredicateWithSubpredicates:[subPreds copy]];
}