Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSSortDescriptor to strip out "the" prefix

I have a bunch of artists stored in CoreData and want to sort them by name but ignoring the prefix "the". So for instance "The Beatles" would be sorted as "Beatles", kinda like what iTunes/iPod does.

So I tried adding a custom cleanName property to my Artist model so it can be used for sorting with:

NSSortDescriptor *sortByName = [[NSSortDescriptor alloc] initWithKey:@"cleanName" ascending:YES];

That obviously brings down the app as cleanName is not a property of the SQLEntity:

...keypath cleanName not found in entity <NSSQLEntity Artist id=1>

I know I could save the cleanName in the store, but it just seems wrong to me. One new attribute just to have the name stripped of the "the" prefix? Really?

So instead, I tried subclassing NSSortDescriptor with a custom compareObject:toObject: implementation:

- (NSComparisonResult)compareObject:(Artist*)artist1 toObject:(Artist*)artist2 {

 NSString *cleanString1 = [artist1.name stringByReplacingOccurrencesOfString:@"the " withString:@"" options:NSCaseInsensitiveSearch range:NSMakeRange(0, [artist1.name length])];
 NSString *cleanString2 = [artist2.name stringByReplacingOccurrencesOfString:@"the " withString:@"" options:NSCaseInsensitiveSearch range:NSMakeRange(0, [artist2.name length])];

 return [artist1.cleanName compare:artist2.cleanName options:NSCaseInsensitiveSearch];
}

This works when I add a new artist, say "The Beatles" to my store. The artist is sorted as "Beatles" and is displayed inside my "B" section. But as soon as I quit the app and relaunch it, I get the following error and the tableview just stays empty:

sectionIndex A for Apparat
sectionIndex B for Bonobo
sectionIndex M for Misteur Valaire
sectionIndex M for Moderat
sectionIndex P for Paul Kalkbrenner
sectionIndex R for Röyksopp
sectionIndex B for The Beatles
NSFetchedResultsController ERROR: The fetched object at index 6 has an out of order section name 'R. Objects must be sorted by section name'

As you can see from what I'm logging, the section titles are fine (The Beatles' section title is B, as it should be). But the sorting is broken, as this record should be right before "Bonobo".

Any idea of how to fix this?

like image 238
samvermette Avatar asked Dec 12 '10 02:12

samvermette


1 Answers

After chatting with a couple of people, it seems like saving the "cleanName" to the database is the best way to go and that "normalization is overrated".

like image 94
samvermette Avatar answered Oct 28 '22 10:10

samvermette