如何过滤具有多个条件的托管对象实体
Posted
技术标签:
【中文标题】如何过滤具有多个条件的托管对象实体【英文标题】:How do I filter a managed object entity with multiple conditions 【发布时间】:2014-08-02 17:42:41 【问题描述】:我可能想错了..
我有一个在实体上工作的搜索/过滤功能。但我希望能够根据几个标准进行过滤..
我有这个:
for (WordEntity *word in [self.fetchedResultsController fetchedObjects])
if ([scope isEqualToString:@"All"] || [word.greekText isEqualToString:searchText ])
NSComparisonResult result = [word.greekText compare:searchText
options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch)
range:NSMakeRange(0, [searchText length])];
if (result == NSOrderedSame)
[self.searchResults addObject:word];
但我希望过滤器同时捕获英语和希腊语文本。我怎样才能最好地做到这一点?谢谢
更新
抱歉,但我仍然无法让它工作..我再次打开它..
按照建议,我将代码更改如下:
[self.searchResults removeAllObjects];
NSLog(@"predicating");
NSPredicate *englishTextPredicate = [NSPredicate predicateWithFormat:@"englishText CONTAINS[cd] %@", searchText];
NSLog(@"eng pred: %@", englishTextPredicate);
NSLog(@"search text: %@", searchText);
[self.fetchedResultsController.fetchRequest setPredicate:englishTextPredicate];
NSArray *fetchedData = [self.fetchedResultsController fetchedObjects];
self.searchResults = [fetchedData copy];
NSLog(@"search count: %i", self.searchResults.count);
但这会产生以下输出。
2014-08-03 07:31:40.846 GuessGreek[16535:425669] Card Count is: 651
2014-08-03 07:31:54.495 GuessGreek[16535:425669] -[WordViewController searchDisplayController:shouldReloadTableForSearchString:]
2014-08-03 07:31:54.495 GuessGreek[16535:425669] -[WordViewController filterContentForSearchText:scope:]
2014-08-03 07:31:54.496 GuessGreek[16535:425669] predicating
2014-08-03 07:31:54.496 GuessGreek[16535:425669] eng pred: englishText.text CONTAINS[cd] "o"
2014-08-03 07:31:54.496 GuessGreek[16535:425669] search text: o
2014-08-03 07:31:54.497 GuessGreek[16535:425669] search count: 651
这是单词的截图。。很明显,前两个单词没有“o”
我做错了什么?
【问题讨论】:
您为什么不使用谓词并为其添加适当的条件? 我知道如何制作谓词,但我无法让谓词与 NSComparisonResult 一起使用。再说一次,也许我想错了.. 您可以直接使用谓词来过滤数组,或者更好的方法是从数据存储中获取(直接或通过更新您的 FRC) 你能给我指出一个代码 sn-p 以便我知道如何做到这一点吗?我更喜欢后一种选择。我只是想不出要使用什么方法。 哎呀。找到了... NSArray *fetchedData = [self.fetchedResultsController fetchedObjects]; 【参考方案1】:使用谓词会更简单。您可以使用复合谓词来搜索两件事。
NSPredicate * pred1 = [NSPredicate predicateWithFormat:@"greekText == %@", searchText];
NSPredicate * pred2 = [NSPredicate predicateWithFormat:@"englishText == %@", searchText];
NSPredicate * compPred = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:pred1,pred2,nil]];
[YourFetchRequestName setPredicate:compPred];
然后执行你的获取请求只会给出你想要的。
self.searchResults = [yourContext executeFetchRequest:YourFetchRequestName error:&error];
希望有帮助!
【讨论】:
谢谢!!那太棒了。我也错过了这个: NSArray *fetchedData = [self.fetchedResultsController fetchedObjects]; 实际上,现在我正在考虑它,这只会返回 greekText 和 englishText 都等于 searchText 的实体......这就是你想要的吗?如果你想要一个或另一个,你可能需要做两个请求。 这就是我的发现。我希望能够搜索希腊词或英文词...我会尝试 orPredicate 抱歉,我不得不重新打开它。我已将谓词简化为只查看一个字段.. 关于您更新的问题...您在哪里执行获取请求?您只是在调用 fetchedObjects,我认为在您再次调用请求之前不会更新它以匹配您的谓词。如果您替换以下行会发生什么:“NSArray *fetchedData = [self.fetchedResultsController fetchedObjects];”与:“NSArray *fetchedData = [self.fetchedResultsController executeFetchRequest:self.fetchedResultsController.fetchRequest error:&error];” ?【参考方案2】:我发现了一些我认为效果很好的东西:
-(void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
[self.searchResults removeAllObjects];
NSLog(@"%s", __FUNCTION__);
for (WordEntity *word in [self.fetchedResultsController fetchedObjects])
NSRange greekResult = [word.greekText rangeOfString:searchText options:NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch];
NSRange englishResult = [word.englishText rangeOfString:searchText options:NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch];
if ( greekResult.location != NSNotFound || englishResult.location != NSNotFound )
[self.searchResults addObject:word];
【讨论】:
以上是关于如何过滤具有多个条件的托管对象实体的主要内容,如果未能解决你的问题,请参考以下文章
使用具有多个搜索条件的 Knex.js 和 SQL 的条件过滤器