Turning an NSArray of custom objects into a alphabetically sectioned UITableView with an index?
(hmm.. long title)
If I start out with an NSArray of custom objects (each object is a Person) like this:
{
surname:Allen forename: Woody,
surname:Baxter forename: Stanley,
surname:Clay forename: Cassius
}
..etc..
You can see that the array is already in surname order. How do I use that array to create a a UITableView with a section headers A, B C etc, as well as an index thing on the side running vertically
A
B
C
EDIT
I guess what I'm asking is how to tu开发者_Python百科rn my array of objects into a Section Array, with all the first letters of the Surnames, and a Surname Array which is perhaps a nested array like this:
{
letter: a
{ surname:Allen forename: Woody }
letter: b
{ surname:Baxter forename: Stanley }
etc
}
In fact, perhaps just a nested array will do.
There are probably a million ways of doing this :) Here's one that might work (I am sure it can be done much prettier, but since no one is answering):
NSMutableDictionary *aIndexDictionary = [[NSMutableDictionary alloc] init];
NSMutableArray *currentArray;
NSRange aRange = NSMakeRange(0, 1);
NSString *firstLetter;
for (Person *aPerson in personArray) {
firstLetter = [aPerson.surname substringWithRange:aRange];
if ([aIndexDictionary objectForKey:firstLetter] == nil) {
currentArray = [NSMutableArray array];
[aIndexDictionary setObject:currentArray forKey:firstLetter];
}
[currentArray addObject:aPerson];
}
Untested...
Joseph Tura's answer has a number of issues, its untested as he mentioned. Here are the issues:
1) [aPerson.name substringWithRange:aRange] will crash if the name is nil or @"";
2) If firstLetter is already in the list of keys, current array is not reset to point to the array object that belongs to the key firstLetter. So if the currentArray previously pointed to an array whose key in the dictionary is 'K', and yet the current firstLetter being 'P' already existing as a key, the name (that starts with the that letter 'P') will be added to the array of names starting with 'k'. Big issue there.
3) Jassie is added to different array to jassie as a result of difference in the case (uppercase and lowercase 'k' are treated differently).
So, as a huge improvement to Joseph's answer, point number 2 being critical, here is a more accurate implementation for future users:
-(NSDictionary*)indexArrayByName:(NSArray*)people
{
NSMutableDictionary *anIndexedDict = [[NSMutableDictionary alloc] init];
NSMutableArray *currentArray = nil;
NSRange aRange = NSMakeRange(0, 1);
NSString *firstLetter;
for(Person *aPerson in people)
{
if(aPerson.name.length)
firstLetter = [[aPerson.name substringWithRange:aRange] uppercaseString];
else
firstLetter = @"noName";//find own way to identify these
if(![anIndexedDict.allKeys containsObject:firstLetter])
{
currentArray = [NSMutableArray array];
anIndexedDict[firstLetter] = currentArray;
}
currentArray = anIndexedDict[firstLetter];
[currentArray addObject:aPerson];
}
return anIndexedDict;
}
Other improvements can be added e.g removing leading white spaces etc, but I just thought I'ld mention the main issues. I tested Joseph's answer for those issues, and then mine to make sure they are eliminated :) .Credit to Joseph for main idea. Cheers.
精彩评论