Note that there are some explanatory texts on larger screens.

plurals
  1. POCore Data: Get Objects with the highest value in each category
    primarykey
    data
    text
    <p>I am currently struggling with my implementation of core data to get a "best of each category" effect - I have already tried to figure out a solution quite a long time now and I just don't get find the right approach &lt;.&lt;</p> <p>I have three subclasses of NSManagedObjects, let's call them "Person", "Child" and "School" for explanatory reasons. Each Person can have multiple children, so there's a to-many relationship between those entities: Person &lt;--->> Child</p> <p>A Child attends a School, one school has many children, so we have: Child &lt;&lt;---> School</p> <p>With this data structure, I want to get a list of <strong>children</strong> structured with these conditions:</p> <ol> <li>the children in the list must match certain requirements (e.g. age, attends certain school, ...) (easily accomplished with a NSPredicate)</li> <li>the list is sorted by the children's grades (or whatever you like, just an attribute)</li> <li><strong>only the best graded child of each parent</strong> that match the requirements (in 1.) is taken into account !</li> </ol> <p>I tried a lot and couldn't figure out a way to go ... the difficult part is to filter the parent's list of children to just get those which are the best graded of each individual parent, what has to be done after applying the requirements of (1.)</p> <p>It would be optimal to wrap it into a NSFetchedResultsController so that the list can easily be displayed by a UITableView.</p> <p>But what is the best approach? Can this be done with a matching predicate? I really appreciate your help!</p> <p>:)</p> <p>EDIT: The problem was solved with the following solution (which is not quite optimal when it's about performance but it does its job =) I replaced the entity names with the ones used in the explanation above. )</p> <p>In Person.m:</p> <pre><code>- (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:&amp;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&amp;&amp;[[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:)]; } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload