views:

1302

answers:

4

I have Two models Department and Worker. Departments has to-many relationship(workers) to worker. Worker has firstName field. How can i get a worker list sorted by firstName by accessing departmet.workers? Is there any way to add sort descriptors in to-many relationship?

+1  A: 

To-many relationships in Core Data are modeled as unordered sets. However, you can create a fetched property on the Department entity that includes a sort descriptor or you can sort set in-memory within your application (NSArrayController will do this for you by setting its sortDescriptors property).

Barry Wark
I'd vote for a fetched property since it seems the "most natural way" in Core Data.
Karsten Silz
+1  A: 

You need to define your own method, such as sortedWorkers. Something like this:

- (NSArray *)sortedWorkers {
    NSSortDescriptor *sortNameDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"firstName" ascending:YES] autorelease];
    NSArray *sortDescriptors = [[[NSArray alloc] initWithObjects:sortNameDescriptor, nil] autorelease];

    return [self.workers sortedArrayUsingDescriptors:sortDescriptors];
}
Hunter
+1  A: 

Hunter's code snip almost worked for me, except since "workers" is an NSSet, I had to load it into an NSMutableArray first:

- (NSArray *)sortedWorkers {
    NSSortDescriptor *sortNameDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"firstName" ascending:YES] autorelease];
    NSArray *sortDescriptors = [[[NSArray alloc] initWithObjects:sortNameDescriptor, nil] autorelease];

    NSMutableArray *sortThese = [NSMutableArray arrayWithCapacity:[self.workers count]];
    for (id worker in self.workers) {
        [sortThese addObject:worker];
    }

    return [sortThese sortedArrayUsingDescriptors:sortDescriptors];
}
Adrian Hosey
+4  A: 

Minor improvement over Adrian Hosey's code:

Instead of manually iterating over all workers you can also just do:

-(NSArray *)sortedWorkers {
  NSSortDescriptor *sortNameDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"firstName" ascending:YES] autorelease];
  NSArray *sortDescriptors = [[[NSArray alloc] initWithObjects:sortNameDescriptor, nil] autorelease];

  return [[self.workers allObjects] sortedArrayUsingDescriptors:sortDescriptors];
}

Probably does exactly the same thing as your iteration internally, but maybe they made it more efficient somehow. It's certainly less typing...

Adrian Schönig