如何过滤具有多个条件的托管对象实体

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 的条件过滤器

在实体框架中加载具有过滤条件的子对象记录

如何通过Django中的prefetch_related过滤具有多个条件的反向外键

如何根据多个条件过滤列表?

在 R dplyr 中过滤具有多个条件名称匹配的数据框

如果您想通过 Core Data 使用多个实体,您需要为每个实体提供一个托管对象上下文吗?