我目前正在努力实现核心数据,以获得“每个类别中最佳”效果 - 我已经尝试找出解决方案很长一段时间了,我只是找不到正确的方法&lt ;。<
我有三个NSManagedObjects的子类,让我们称它们为“Person”,“Child”和“School”,原因是出于解释。每个人可以有多个孩子,因此这些实体之间存在多对多的关系: 人< --->>子
一个孩子上学,一所学校有很多孩子,所以我们有: 儿童<< --->校
有了这个数据结构,我想得到一个由这些条件构成的孩子列表:
我尝试了很多但无法找到方法......困难的部分是过滤父母的孩子列表,以获得每个父母的最佳等级,必须做什么在应用(1。)
的要求之后最好将它包装到NSFetchedResultsController中,以便UITableView可以轻松显示列表。
但最好的方法是什么?这可以用匹配的谓词来完成吗?我真的很感谢你的帮助!
:)
编辑:问题是通过以下解决方案解决的(当它关于性能时它不是最佳但它完成它的工作=)我用上面的解释中使用的实体名称替换了实体名称。 )在Person.m中:
- (NSArray *)bestChildrenWithPredicate:(NSPredicate *)aPredicate { // create request
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:@"Child" inManagedObjectContext:moc]];
// set predicate to fetch only children of current person and those that fit in the given predicate (possible to get back children of multiple schools)
NSPredicate *thePredicate = [NSPredicate predicateWithFormat:@"parent == %@",self];
if (aPredicate) thePredicate = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:thePredicate, aPredicate, nil]];
[request setPredicate:thePredicate];
// sort results for grade and execute request
[request setSortDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"grade" ascending:YES]]];
NSError *error = nil;
NSArray *sortedResultsForPredicate = [moc executeFetchRequest:request error:&error];
[request release];
if (!sortedResultsForPredicate) {
// handle error
abort();
}
// create dictionary with schools as keys
NSMutableDictionary *bestResults = [[[NSMutableDictionary alloc] init] autorelease];
// loop through all results
for (Child *aResult in sortedResultsForPredicate) {
// get string for dictionary index
NSString *theSchoolKey = aResult.school.key;
// check if the school already exists in the dictionary
if (![bestResults objectForKey:theSchoolKey]) {
[bestResults setObject:aResult forKey:theSchoolKey];
} else {
// get the current result
Result *preResult = [bestResults objectForKey:theSchoolKey;
// compare the results by grade and replace if new one is better
NSComparisonResult comp = [preResult compareByGrade:aResult];
if (comp==NSOrderedDescending||(comp==NSOrderedSame&&[[aResult valueForKey:@"date] compare:[preResult valueForKey:@"date"]]==NSOrderedAscending)) {
[bestResults setObject:aResult forKey:theSchoolKey];
}
}
}
// return best graded children of each school sorted by date
return [[bestResults allValues] sortedArrayUsingSelector:@selector(compareByDate:)];
}
答案 0 :(得分:1)
如果你将你的父母留在一个单独的实体中,并且在子实体中有一个关系,那么你应该能够遍历父列表,只为该父项提取子项,将结果读入已排序的数组,以及使用[myArray lastResult]弹出最后一个值;然后,您可以将此对象添加到可在应用程序中访问的可变数组中。我没有时间把它放到代码中,但基础是:
Fetch the parents entity into an array
Iterate the parents array, using the parent as the constraint for the child entity, and use NSSortDescriptor initWithKey:@"grade" (or whatever you call it) ascending:YES.
Read the results into a resultsArray
id bestKid = [resultsArray lastObject];
[myNSMutableArray addObject:bestKid];
为每个父对象执行此操作,然后myNSMutableArray将包含最佳小孩记录的数组。
现在,我比直接SQL更熟悉核心数据,所以如果这个解决方案不可行,我欢迎更正! :)