嵌套对象IOS的NSPredicate问题

时间:2014-12-05 06:47:19

标签: ios8 nsmutablearray nsarray subquery nspredicate

我如何在" self.tableInfo"上使用NSPredicateNSMutableArray)使用谓词键" name"来获取CheckIn的对象具有以下结构。由于self.tableInfo有一个SectionInfo数组,每个SectionInfo里面都有它的单元格(CellInfo),每个单元格都有checkin对象。

- (void)configureView   {
    self.tableInfo = [NSMutableArray alloc]init];
    self.filteredTableInfo = [NSMutableArray alloc]init];
    NSArray *checkIns =  [CheckIn MR_findAll];
    SectionInfo*checkInSection = [SectionInfo section];
    for (CheckIn *checkIn in checkIns) {
        CellInfo *listCell = (CellInfo *)[CellInfo cell];
        listCell.className = NSStringFromClass([FeedListCell class]);
        listCell.height = 260;
        listCell.object = checkIn;
        [checkInSection.cells addObject:listCell];
    }
    if ([checkIns count] > 0) {
        self.tableInfo = [NSMutableArray arrayWithArray:@[checkInSection]];
        self.filteredTableInfo = self.tableInfo;
        [self.tableView setHidden:NO];
        [self.tableView reloadData];
    }
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    if (self.tableInfo) {
        return self.tableInfo.count;
    }
    return 0;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    if (self.tableInfo && (section < self.tableInfo.count) ) {
        SectionInfo *sectionInfo = [self.tableInfo objectAtIndex:section];
        return sectionInfo.numberOfCells;
    }
    return 1;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    SectionInfo *sectionInfo = self.tableInfo[indexPath.section];
    CellInfo *formInfoCell = sectionInfo.cells[indexPath.row];
    CheckIn *checkin = formInfoCell.object;
    NSLog(@"%@", checkIn.name);
}

我使用的方式如下:

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
    if([searchText length] != 0) {
        [self filterContentForSearchText:searchText];
    }
}
- (void)filterContentForSearchText:(NSString *)searchText   {
    NSPredicate *namePredicate = [NSPredicate predicateWithFormat:@"ANY cells.object.name contains[c] %@", searchText];
    NSArray * filteredArray = [self.filteredTableInfo filteredArrayUsingPredicate:namePredicate];
    self.tableInfo = [NSMutableArray arrayWithArray:@[filteredArray]];
    [self.tableView reloadData];
}

这使我总是零计数。还有更好的办法处理这件事吗?

2 个答案:

答案 0 :(得分:1)

看起来你对这个谓词有几个问题。首先,在你的谓词中,你正在搜索基于“CellInfo.object”SELF.cells.object contains[c] %@而不是“CellInfo.object.name”,就好像你想要做的那样。

其次,在数组中搜索数组时(在您的tableInfo数组中的SectionInfo.cells中),您不能简单地使用点表示法来搜索内部数组。您必须在数组中指定与查询匹配的项目。您可以使用其中一个关键字ANY ALLNONE来完成此操作。

例如,要获取任何具有CheckIn.name包含搜索文本的CellInfo的SectionInfo,您需要执行此操作:

NSPredicate *namePredicate = [NSPredicate predicateWithFormat:@"ALL cells.object.name contains[c] %@", searchText"];
NSArray *filteredSections = [self.tableInfo filteredArrayUsingPredicate:namePredicate]

然而,这会返回一个SectionInfo数组,而不是你想要的CheckIn对象。要获取CheckIn对象,必须首先创建所有CheckIn对象的数组。您可以使用NSArray上的valueForKeyPath方法执行此操作。然后,您可以使用更简单的谓词搜索该数组。

NSArray *allCheckInObjects = [self.tableInfo valueForKeyPath:@"@distinctUnionOfArrays.cells.object"];
NSPredicate *namePredicate = [NSPredicate predicateWithFormat:@"name contains[c] %@", searchText];
NSArray *filteredCheckInObjects = [allCheckInObjects filteredArrayUsingPredicate:namePredicate];

希望这有帮助!

答案 1 :(得分:0)

我通过以下代码解决。我在单个数组中有“Recent”和“Other”数组我在每个数组中应用谓词。和搜索条件是“from_user”NSDictionary中的“name”。

-(void)filterContentForSearchText:(NSString *)searchText
{
    [self.filterResultArray removeAllObjects];
    NSPredicate *namePredicate = [NSPredicate predicateWithFormat:@"(from_user.name contains[cd] %@)", searchText];

    NSMutableArray *recentSearch=[[NSMutableArray alloc] init];
    //Recent
    if ([[[self connectioUserArray] objectAtIndex:1] count]==0) {
        //Recent is blank
    }
    else{
        //else
        recentSearch=[[[[self connectioUserArray] objectAtIndex:0] filteredArrayUsingPredicate:namePredicate] mutableCopy];
    }

    //other
    self.filterResultArray = [[[[self connectioUserArray] objectAtIndex:1] filteredArrayUsingPredicate:namePredicate] mutableCopy];

    if ([recentSearch count]==0) {
        //no records
    }
    else{
        //if recent records
        for (NSMutableDictionary *recentConnectoin in recentSearch) {
            [self.filterResultArray addObject:recentConnectoin];
        }
    }

    //Reload table view
    [self.tableView reloadData];

}