0

I would like the NSFetchRequest for my UITableViewController to group similar records (entities) based upon a particular attribute. I currently do a two-step process, but I believe there might be someway to use an + (NSExpression *)expressionForAggregate:(NSArray *)collection.

Could someone help with the appropriate code?

Here's the code for my two step process that returns an array of an array:

+(NSArray *)getTopQforDogByProgram2:(Dog *)dog
                     inProgram:(RunProgramTypes)programType
              inManagedContext:(NSManagedObjectContext *)context {
    NSString *searchString;

    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Run"];
    request.predicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"dog.callName = '%@'",dog.callName]];
    NSSortDescriptor *classSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"runClass" ascending:NO];
    request.sortDescriptors = [NSArray arrayWithObject:classSortDescriptor];

    NSError *error = nil;
    NSArray *dataArray = [context executeFetchRequest:request error:&error];

    NSMutableArray *returnArray = [[NSMutableArray alloc] init];
    if ( [dataArray count] > 0 ) {
        NSMutableArray *pointArray = [[NSMutableArray alloc] init];
        for ( Run *run in dataArray ) {
            if ( ! [returnArray count] ) {
                [pointArray addObject:run];
                [returnArray addObject:pointArray];
            } else {
                BOOL wasSame = FALSE;
                for ( NSMutableArray *cmpArray in returnArray ) {
                    Run *cmpRun = [cmpArray lastObject];
                    if ( cmpRun.runClass   == run.runClass ) {
                        [cmpArray addObject:run];
                        wasSame = TRUE;
                        break;
                    }
                }
                if ( ! wasSame ) {
                    pointArray = [[NSMutableArray alloc] init];
                    [pointArray addObject:run];
                    [returnArray addObject:pointArray];

                }
            }
        }
    }
    return returnArray;
}
Kirk
  • 16,182
  • 20
  • 80
  • 112

1 Answers1

0

You could use a fetch results controller to do the sectioning for you like this:

NSFetchedResultsController* controller = [[NSFetchedResultsController alloc] initWithFetchRequest:request
                                                                         managedObjectContext:context
                                                                           sectionNameKeyPath:@"runClass"
                                                                                    cacheName:nil];
NSMutableArray* sections = [[NSMutableArray alloc] initWithCapacity:[controller sections] count];
for (id<NSFetchedResultsSectionInfo> section in [controller sections]) {
    NSMutableArray* sectionCopy = [NSMutableArray arrayWithArray:[section objects]];
    [sections addObject:sectionCopy];
}

Or do it yourself with: (given that the results are sorted by runClass)

NSMutableArray* sections = [NSMutableArray new];
NSMutableArray* currentSection = [NSMutableArray new];
for (Run* run in dataArray) {
    Run* lastObject = (Run*)[currentSection lastObject];
    if (lastObject && (run.runClass == lastObject.runClass)) {
        currentSection = [NSMutableArray new];
        [sections addObject:currentSection];
    }
    [currentSection addObject:run];
}
Dan Shelly
  • 5,991
  • 2
  • 22
  • 26