views:

1121

answers:

1

I'm currently trying to sort my array of objects into day order so they can be grouped in the correct order i.e. Monday, Tuesday, Wednesday then by start time.

Only problem is I can't figure out how to do this, my code currently looks like this: Which sorts alphabetically then by time:

NSString *sectionKey = nil;
switch (tab) {

case kByWeekA: {
NSSortDescriptor *sortDescriptor1 = [[NSSortDescriptor alloc] initWithKey:@"day" ascending:NO];
NSSortDescriptor *sortDescriptor2 = [[NSSortDescriptor alloc] initWithKey:@"starttime" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor1, sortDescriptor2, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
[sortDescriptor1 release];
[sortDescriptor2 release];
[sortDescriptors release];
sectionKey = @"day";
break;
}
case kByWeekB:{
NSSortDescriptor *sortDescriptor1 = [[NSSortDescriptor alloc] initWithKey:@"day" ascending:YES];
NSSortDescriptor *sortDescriptor2 = [[NSSortDescriptor alloc] initWithKey:@"starttime" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor1, sortDescriptor2, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
[sortDescriptor1 release];
[sortDescriptor2 release];
[sortDescriptors release];
sectionKey = @"day";
break;
}
default:
break;
}

Please help!

+1  A: 

I see two solutions:

  1. Create a custom comparison for your sort descriptor that looks at the "day" key and orders them as desired. See Specifying Custom Comparisons here.
  2. Make the "day" key into an integer and use an enumeration for the day values in the desired order.

UPDATE 2 Example code for option 2:

-Change the "day" attribute to a number (Int16) and add a transient (non-persistant) "dayName" string attribute.

-Add this enumeration of the week days:

typdef enum {
    kMonday,
    kTuesday,
    kWednesday,
    kThursday,
    kFriday,
    kSaturday,
    kSunday
} WeekDay;

-Set the "day" property of your managed objects to be NSNumber objects. For example:

object.day = [NSNumber numberWithInteger:kMonday];

-Implement the getter function for the transient "dayName" property:

- (NSString*)dayName {
    switch ((WeekDay)self.day.integerValue) {
        case kMonday:
            return @"Monday";
            break;
        case kTuesday:
            return @"Tuesday";
            break;
        case kWednesday:
            return @"Wednesday";
            break;
        case kMonday:
            return @"Monday";
            break;
        case kThursday:
            return @"Thursday";
            break;
        case kFriday:
            return @"Friday";
            break;
        case kSaturday:
            return @"Saturday";
            break;
        case kSunday:
            return @"Sunday";
            break;
    }
}

-In the fetch request, sort by "day" and use "dayName" as the section name key path.

UPDATE
Note: Option 1 works fine for sorting an array, but Core Data is throwing an 'NSInvalidArgumentException' exception for 'unsupported NSSortDescriptor selector: weekdayCompare:'

Example code for option 1:

// category on NSString for custom comparison
@interface NSString (WeekdayComparison)
- (NSComparisonResult)weekdayCompare:(NSString*)otherDay;
@end
@implementation NSString (WeekdayComparison)
- (NSComparisonResult)weekdayCompare:(NSString*)otherDay {
    NSArray *weekDays = [NSArray arrayWithObjects:@"Sunday", @"Monday", @"Tuesday", @"Wednesday", @"Thursday", @"Friday", @"Saturday", nil];

    NSUInteger selfIndex = [weekDays indexOfObject:self];
    NSUInteger otherDayIndex = [weekDays indexOfObject:otherDay];

    if (selfIndex < otherDayIndex) {
        return NSOrderedAscending;
    }
    else if (selfIndex > otherDayIndex) {
        return NSOrderedDescending;
    } else {
        return NSOrderedSame;
    }
}
@end

To use the new comparison method:

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"day" ascending:YES selector:@selector(weekdayCompare:)];
NSArray *sortDescriptors = [NSArray arrayWithObjects:sortDescriptor, nil];
[sortDescriptor release];
gerry3
I would like to do it using the first solution but am struggling! Im trying to compare the day key to an array of day strings but can't get it to work? Any suggestions or hints of how i can implement the first solution? Many Thanks
Myke Hamilton
I updated my answer with a code example.
gerry3
I've implemented the comparison in a new class, and changed the "self" in the method call to "day" but get 'NSInvalidArgumentException', reason: 'unsupported NSSortDescriptor selector: weekdayCompare:'error. Am I implementing it in the wrong place?
Myke Hamilton
if i went for the second solution how would i show the int as a string, if NSInteger day = 0 then display Monday... any help would be greatly appreciated!
Myke Hamilton
The comparison method is in a "category". You can just put both its interface and implementation at the top of the implementation (.m) file where you plan to use it. You can also put it in separate files, but you have to import the header (.h).
gerry3
With the second solution you would create a method to return the string given the integer (using a switch statement).
gerry3
With the first solution I've added the sort both the interface and implementation at the top of the .m file where I'm using it. But I still keep getting the *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'unsupported NSSortDescriptor selector: weekdayCompare:' error. And I dont know why?
Myke Hamilton
Your key is "day" correct? And the managed objects that you are sorting have a STRING attribute named "day"?
gerry3
yea thats correct but its still not working. I've been stuck on this one area for over a week its so frustrating. I didn't think it would be so difficult to sort by day!
Myke Hamilton
It's driving me crazy lol! Any ideas?
Myke Hamilton
I am not sure. My code definitely works. I just tested it with objects with a string property named "day" and "day" as the sort key. Can you make an update to your question with the current code that you are using?
gerry3
Hi, Would it be easier if I sent you a zip file with my project in and see if you could spot the problem?, It would really help me as it's been over a week being stuck on the same problem! Would be very appreciated! Thank you in advance.
Myke Hamilton
Any chance you could take a look, I'm still stuck in front of the computer! Thank you, Myke
Myke Hamilton
Sure, you can send it. Just click through my profiles.
gerry3
Hi Gerry, I can't attach the Zip to the profile email, could you send me your email address to [email protected], then I will send you back the Zip file. Thank you for all your support
Myke Hamilton