title: How can I do a case insensitive sort of NSFetchedResultsController that also ignores words like "the"?
body: <p>I'm working on a Core Data driven app that has 2 entities requiring special sorting considerations in the <code>NSFetchedResultsController</code>.</p>
  
  <p>The simpler case of the 2 just requires ignoring "The" so that (&amp; I'm citing real data examples) The Planting Festival follows Peats Ridge Festival in the sort order. As a safety I'd also like to make that sort case insensitive. For that one I tried the suggestions here <a href="https://stackoverflow.com/questions/2796560/how-can-i-sort-an-nstablecolumn-of-nsstrings-ignoring-the-and-a">How can I sort an NSTableColumn of NSStrings ignoring &quot;The &quot; and &quot;A &quot;?</a> by adding...</p>
  
  <pre><code>@property (nonatomic, readonly) NSString * sortname;
  </code></pre>
  
  <p>to the interface of my entity definition class &amp;...</p>
  
  <pre><code>- (NSString *)sortname
  {
      NSMutableString *temp = [NSMutableString stringWithString:[[self name] lowercaseString]];
      if ([temp hasPrefix:@"the "]) {
          return [temp substringFromIndex:4];
      }
      return temp;
  }
  </code></pre>
  
  <p>to the implementation but the app crashes when I give it <code>@"sortname"</code> as the key for the <code>NSSortDescriptor</code>.</p>
  
  <p>The 2nd entity is more complicated. In addition to stripping "The" for sorting there is also "A" &amp; honorifics like "Dr" &amp; "Professor" but not always. An example in data is Professor Ian Lowe &amp; Professor Wallace's Puppet Theatre. Ian Lowe is a real person who (much as I respect him) should be sorted under I for Ian but there is no Professor Wallace, that's just the name on a, well, puppet theatre &amp; it should be sorted under P. For that selective aspect of it I see no way other than having a boolean attribute on the entity specifies whether or not to strip the 1st word for sorting purposes.</p>
  
  <p>For the rest of it the question comes down to... Is there a way to create a (for want of knowing a more correct term) virtual attribute on a Core Data entity that will work when I pass its name as the key for an <code>NSSortDescriptor</code> of an <code>NSFetchedResultsController</code>?</p>
  
  <p>The desperate approach, which I'd rather not take, would be to create real <code>sortname</code> attributes on those 2 entities &amp; calculate the values as I populate the entities.</p>
  
  <p>Update...
  Attempting to follow TechZen's answer this is the constructor for my NSFetchedResultsController...</p>
  
  <pre><code>- (NSFetchedResultsController *)frc
  {
      if (_frc) return _frc;
  
      NSFetchRequest *request = [[NSFetchRequest alloc] init];
      NSEntityDescription *entity = [NSEntityDescription entityForName:@"EventProfile"
                                                inManagedObjectContext:_moc];
      [request setEntity:entity];
      NSSortDescriptor *sorter = [[NSSortDescriptor alloc] initWithKey:@"name"
                                                             ascending:YES
                                                            comparator:^NSComparisonResult(id obj1, id obj2) {
          NSMutableString *sortname1 = [NSMutableString stringWithString:[obj1 lowercaseString]];
          if ([sortname1 hasPrefix:@"the "]) {
              sortname1 = [NSMutableString stringWithString:[sortname1 substringFromIndex:4]];
          }
          NSMutableString *sortname2 = [NSMutableString stringWithString:[obj2 lowercaseString]];
          if ([sortname2 hasPrefix:@"the "]) {
              sortname2 = [NSMutableString stringWithString:[sortname2 substringFromIndex:4]];
          }
          return [sortname1 compare:sortname2];
      }];
  
      [request setSortDescriptors:[NSArray arrayWithObject:sorter]];
      [sorter release], sorter = nil;
      [request setFetchBatchSize:15];
  
      NSFetchedResultsController *frcTemp = [[NSFetchedResultsController alloc] initWithFetchRequest:request
                                                                                managedObjectContext:_moc
                                                                                  sectionNameKeyPath:nil
                                                                                           cacheName:[NSString GetUUID]];
      [self setFrc:frcTemp];
      [_frc setDelegate:self];
      [frcTemp release], frcTemp = nil;
      [request release], request = nil;
  
      if ([[_frc fetchedObjects] count] == 0) {
          //&lt;#statements#&gt;
      }
  
      return _frc;
  }
  </code></pre>
  
  <p>However it is still sorting by name. I inserted an "I'm here." log line in the comparator block &amp; that didn't appear in my logs leading me to think the comparator isn't even being executed.</p>
  
  <p>Cheers &amp; TIA, Pedro :)</p>