Ios8 嵌套对象的NSPredicate问题

Ios8 嵌套对象的NSPredicate问题,ios8,nsmutablearray,nsarray,subquery,nspredicate,Ios8,Nsmutablearray,Nsarray,Subquery,Nspredicate,如何使用“self.tableInfo”(NSMutableArray)上的NSPredicate,使用谓词键“name”以以下结构获取签入的对象。因为self.tableInfo有一个SectionInfo数组,每个SectionInfo都有自己的单元格(CellInfo),每个单元格都有签入对象 - (void)configureView { self.tableInfo = [NSMutableArray alloc]init]; self.filteredTableI

如何使用“self.tableInfo”(
NSMutableArray
)上的
NSPredicate
,使用谓词键“name”以以下结构获取签入的
对象。因为self.tableInfo有一个SectionInfo数组,每个SectionInfo都有自己的单元格(CellInfo),每个单元格都有签入对象

- (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);
}

这使我始终返回零计数。有更好的方法来处理这个问题吗?

看起来这个谓词有一些问题。首先,在谓词中,您是根据“CellInfo.object”
SELF.cells.object包含[c]@
而不是您似乎想要的“CellInfo.object.name”进行搜索的

其次,在数组中搜索数组时(在tableInfo数组中的SectionInfo.cells中),不能简单地使用点符号来搜索内部数组。必须指定数组中与查询匹配的项。您可以使用关键字
ANY
ALL
NONE
执行此操作

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

NSPredicate *namePredicate = [NSPredicate predicateWithFormat:@"ALL cells.object.name contains[c] %@", searchText"];
NSArray *filteredSections = [self.tableInfo filteredArrayUsingPredicate:namePredicate]
但是,这将返回一个SectionInfo数组,而不是您想要的签入对象。为了获得签入对象,必须首先创建所有签入对象的数组。您可以通过在NSArray上使用
valueForKeyPath
方法来实现这一点。然后可以使用更简单的谓词搜索该数组

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

希望这有帮助

我通过以下代码求解。我在单个数组中有“最近”和“其他”数组,我在每个数组中应用谓词。搜索条件是“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];

}

谢谢我尝试过使用您的方法,例如:NSPredicate*namepirecte=[NSPredicate predicate-withformat:@“ALL cells.object.name包含[c]@”,searchText];NSArray*filteredSections=[self.tableInfo filteredArrayUsingPredicate:namePredicate];但结果总是一个空数组。我需要sectionInfo对象。您确定self.tableInfo在搜索之前已初始化并填充吗?我将NSLog()数组,并确保您可以找到您正在使用谓词搜索的对象,以确保它确实是失败的谓词。是的,我再次检查了它。以下是我在控制台中使用“Po self.tableInfo”以及使用NSLog()时的日志。NSLog(@“self.tableInfo在谓词之前:%@”,self.tableInfo);谓词之前的self.tableInfo:(“”)NSLog(@“filteredSections:%@”,filteredSections);filteredSections:()NSLog(@“filteredSections数组计数:%lu”,(无符号长)[filteredSections计数]);filteredSections数组计数:0我确信搜索键“a”在我的签入对象中。啊,我看到了问题。我错误地指定了
ALL
,而不是
ANY
ALL
要求该节中的每个单元格必须与谓词匹配
ANY
指定与谓词匹配的任何单元格都足够了。使用
ANY
我用了“ANY”而不是“ALL”。现在它显示了一个sectionInfo对象,sectionInfo中的单元格数为零。我可以做子查询吗?像这样的:
-(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];

}