How do I create an Objective-C NSDictionary of NSArrays without reusing the same NSArray?

iphone, nsmutablearray, nsmutabledictionary, objective-c

Solution

I think you want to do something like this:

NSMutableDictionary *places = [[NSMutableDictionary alloc] init];

// initialize places with an array for each letter
NSString *alphabet = [[NSString alloc] initWithString:@"ABCDEFGHIJKLMNOPQRSTUVWXYZ"];
for (int x = 0; x < 26; x++) {
    NSString *letter = [alphabet substringWithRange:NSMakeRange(x, 1)];
    [places setObject:[NSMutableArray array] forKey:letter];
}

// then put each place in the array corresponding to its first letter
for (NSString *place in allPlaces) {
    NSString *first = [[place substringWithRange:NSMakeRange(0, 1)] uppercaseString];
    NSMutableArray *letterArray = [places objectForKey:first];
    [letterArray addObject:place];
}

Problem

Long time Windows developer, 1st time Objective-C/iPhone developer wants to create a NSDictionary of NSArrays that can be displayed in a plain UITableView with alphabetic sections. The source for this dictionary of arrays is an array containing store names sorted alphabetically: Apple Store Atlanta Bread Company Borders Build-A-Bear Workshop Cargill Gallery Dillards Dick's Sporting Goods Eddie Baure FootLocker GameStop Heizberg Diamonds LensCrafters McDonald's Nordstrom Payless Shoe Source Pottery Barn Solstice Starbucks Coffee Victoria's Secret White Barn Candle Co. The dictionary of arrays that's created from the source should look something like this (datatype in parenthesis): Root (Dictionary) ....A (Array) ........Apple Store (String) ........Atlanta Bread Company (String) ....B (Array) ........Borders (String) ........Build-A-Bear Workshop (String) ....C (Array) ........Cargill Gallery (String) ....D (Array) ........Dillards (String) ........Dick's Sporting Goods (String) ....etc. A dictionary of arrays like the above structure populates the TableView and displays like this: A Apple Store Atlanta Bread Company B Borders Build-A-Bear Workshop C Cargill Gallery D Dillards Dick's Sporting Goods etc. The code I've written that creates the dictionary of arrays ends up putting the last store (White Barn Candle Co.) after every section header. A White Barn Candle Co. B White Barn Candle Co. C White Barn Candle Co. D White Barn Candle Co. etc. I realize this is happening because I reuse a temporary array, populating it with the A's, clearing it out, populating it with the B's, clearing it out, etc. Here's the actual code that creates the dictionary of arrays from the source array. ``` NSMutableDictionary *places = [[NSMutableDictionary alloc] init]; NSMutableArray *alphaPlace = [[NSMutableArray alloc] init]; for (int x = 1; x <= 26; x++) { NSString *alphabet = [[NSString alloc] initWithString:@"ABCDEFGHIJKLMNOPQRSTUVWXYZ"]; NSString *letter = [alphabet substringWithRange:NSMakeRange(x - 1, 1)]; for (NSString *place in allPlaces) { NSString *first = [place substringWithRange:NSMakeRange(0, 1)]; if ([first isEqualToString:letter] == YES) { // Add to alphaPlace [alphaPlace addObject:place]; } else { // Add alphaPlace to places, clear out alphaPlace; add new item to alphaPlace [places setValue:alphaPlace forKey:letter]; [alphaPlace removeAllObjects]; // SAME ARRAY BEING USED FOR ALL LETTERS OF ALPHABET! [alphaPlace addObject:place]; } } } ``` I realize I could "brute force" this by creating 26 distinct arrays and using a switch statement to select the correct one to populate but I really don't want to do that. I thought someone more familiar with Objective-C could provide me with a more elegant solution. Thanks in advance. Let me know if you need more info.

Original source