嵌套对象 IOS 的 NSPredicate 问题
Posted
技术标签:
【中文标题】嵌套对象 IOS 的 NSPredicate 问题【英文标题】:NSPredicate issue for Nested objects IOS 【发布时间】:2014-12-05 06:47:19 【问题描述】:我如何在“self.tableInfo”(NSMutableArray
) 上使用NSPredicate
使用具有以下结构的谓词键“name”来获取CheckIn
的对象。因为 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);
我使用的方式是这样的:
- (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];
这总是返回零计数。有更好的办法来处理这件事吗?
【问题讨论】:
【参考方案1】:看起来您在使用此谓词时遇到了一些问题。首先,在您的谓词中,您正在搜索基于“CellInfo.object”SELF.cells.object contains[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 数组,而不是您想要的 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];
希望这会有所帮助!
【讨论】:
谢谢。我尝试使用您的方法,例如: NSPredicate *namePredicate = [NSPredicate predicateWithFormat:@"ALL cells.object.name contains[c] %@", searchText]; NSArray *filteredSections = [self.tableInfo filteredArrayUsingPredicate:namePredicate];但结果始终是一个空数组。我需要 sectionInfo 对象。 您确定 self.tableInfo 在搜索之前已初始化并填充吗?我会 NSLog() 数组并确保您可以使用谓词找到要搜索的对象,以确保它确实是失败的谓词。 是的,我再次检查过。这是我在控制台中使用“Po self.tableInfo”以及使用 NSLog() 时的日志。 NSLog(@"self.tableInfo before predicate :%@", self.tableInfo);谓词前的 self.tableInfo :( "ALL
而不是ANY
。 ALL
要求该部分中的每个单元格都必须与谓词匹配。 ANY
指定任何匹配谓词的单元格就足够了。使用ANY
我使用了“ANY”而不是“ALL”。现在它向我显示了一个 sectionInfo 对象,并且 sectionInfo 内部的单元格计数为零。我可以做子查询吗?像这样的东西:***.com/questions/13242383/…【参考方案2】:
我通过以下代码解决。我在单个数组中有“最近”和“其他”数组我在每个数组中应用谓词。并且搜索条件是“from_user”NSDictionary 中的“名称”。
-(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];
【讨论】:
以上是关于嵌套对象 IOS 的 NSPredicate 问题的主要内容,如果未能解决你的问题,请参考以下文章