views:

422

answers:

2

I am working on converting a plain tableview to a sectioned tableview. I would like the section titles to be the first letter for the items in the section.

This is what I have so far in my titleForHeaderInSection method:

NSSortDescriptor *sortDescriptor;
sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"Name"
             ascending:YES] autorelease];
NSArray *sortedArray;
NSMutableArray *commonNameArray = [tableDataSource valueForKey:@"Name"];

NSArray *uniquearray;
uniquearray = [[NSSet setWithArray:commonNameArray] allObjects];
sortedArray = [uniquearray sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];

This code removes the duplicate titles and sorts the list alphabetically. Now I just need to convert the strings in the array to the first letters only. What is the best way to go about this?

+2  A: 
NSMutableSet *firstCharacters = [NSMutableSet setWithCapacity:0];
for( NSString *string in [tableDataSource valueForKey:@"Name"] )
    [firstCharacters addObject:[string substringToIndex:1]];

NSArray *uniquearray = [[firstCharacters allObjects] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
groundhog
Thanks! This is a bit more elegant than the solution I came up with below. I just added: return [uniquearray objectAtIndex:section];and it works like a charm.
Jonah
Not just elegant - but also much more efficient... You should not be doing this in a titleForHeaderInSection: too - you should retain your uniqueArray as a member variable and released at dealloc.Your is creating an array of all the names, a sorted version, then picking out one element and getting the first character. Mine is making a set of only the first characters, then a sorted version - both of which are at most 36 characters long (instead of # characters in all members for CommonName)
groundhog
Thanks for the suggestions. I have now placed the declaration of unique in the viewDidLoad method and then called: return [arrayOfInitialLetters objectAtIndex:section];in the titleForHeaderInSection method.
Jonah
There *really* needs to be a check for -length on string before attempting to invoke -substringToIndex:. If the string is empty, NSString will throw an exception.
retainCount
A: 

Thanks for the help. In a rare moment of inspiration I just got it working. Here's what I did. Anyone see anything wrong with doing it this way?

-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
     NSSortDescriptor *sortDescriptor;
     sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"CommonName"
    ascending:YES] autorelease];
     NSArray *sortedArray;
     NSMutableArray *commonNameArray = [tableDataSource valueForKey:@"CommonName"];

     NSArray *uniquearray;
     uniquearray = [[NSSet setWithArray:commonNameArray] allObjects];
     sortedArray = [uniquearray sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];

     NSString *stringForFirstLetter = [[sortedArray objectAtIndex:section] substringToIndex:1];

return stringForFirstLetter;}
Jonah