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

时间:2011-07-07 18:04:26

标签: iphone objective-c ios core-data nspredicate

我目前正在努力实现核心数据,以获得“每个类别中最佳”效果 - 我已经尝试找出解决方案很长一段时间了,我只是找不到正确的方法&lt ;。<

我有三个NSManagedObjects的子类,让我们称它们为“Person”,“Child”和“School”,原因是出于解释。每个人可以有多个孩子,因此这些实体之间存在多对多的关系: 人< --->>子

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

有了这个数据结构,我想得到一个由这些条件构成的孩子列表:

  1. 列表中的孩子必须符合某些要求(例如年龄,就读某个学校......)(使用NSPredicate很容易完成)
  2. 列表按孩子的成绩(或任何你喜欢的,只是属性)排序
  3. 仅考虑符合要求(在1.中)的每个父母的最佳分级孩子!
  4. 我尝试了很多但无法找到方法......困难的部分是过滤父母的孩子列表,以获得每个父母的最佳等级,必须做什么在应用(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:)];
    
    }
    

1 个答案:

答案 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更熟悉核心数据,所以如果这个解决方案不可行,我欢迎更正! :)