核心数据:获取每个类别中具有最高价值的对象

问题描述:

我目前正在努力实现核心数据以获得“最佳的每个类别”效果 - 我已经试图找出相当长时间的解决方案了我只是没有找到正确的方法<。 <核心数据:获取每个类别中具有最高价值的对象

我有三个NSManagedObjects的子类,让我们称他们为“Person”,“Child”和“School”以解释原因。每个人都可以有多个孩子,所以有这些实体之间的多对多关系: 人< --- >>儿童

一个孩子参加一所学校,一个学校有很多孩子,所以我们有: 儿童< < --->学校

有了这种数据结构,我想儿童这些条件构成的列表:

  1. 在列表中的孩子必须有一定的要求相匹配(如年龄,安泰信DS某些学校,...)(容易与NSPredicate完成)
  2. 列表是由孩子的成绩(或任何你喜欢的,只是一个属性)
  3. 只有每个父的最好的分级子排序时考虑到匹配要求(在1中)!

我尝试了很多,想不出一种方法去......困难的部分是过滤父母的孩子列表,以获得那些每个父母的最好分级,那些有什么在应用(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:)]; 

} 

如果你保持在一个单独的实体,你的父母,并在儿童实体的关系,那么你应该能够通过父列表进行迭代,只有拉为那个父节点的子节点,将结果读入一个有序数组,并使用[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,因此如果此解决方案不可行,我欢迎更正!:)

+0

嗨xianritchie,非常感谢你的回答:)就在此之前,我骑了一辆自行车,正如我最近经历的那样,这对于刷新自己的想法可能相当有帮助 - 好吧,我来了有一个非常相似的想法,并能够在你的帮助下实现它:)谢谢! (我将在上面的问题中编辑我的解决方案) – knl