开发者

Different Keys Point to Same Object(s) in NSMutableDictionary

开发者 https://www.devze.com 2023-02-03 22:59 出处:网络
I have a custom object called Person that among other things contains an NSString field called descriptor, which stores what sort of person that Person object is (angry, sad, wild, happy, morose, etc)

I have a custom object called Person that among other things contains an NSString field called descriptor, which stores what sort of person that Person object is (angry, sad, wild, happy, morose, etc). All of my Person objects are in an NSMutableArray, but I would like to store them in an NSMutableDictionary in such a manner:

Key: A, Object: An NSMutableArray where all Person objects have descriptor starting with 'A'

Key: B, Object: An NSMutableArray where all Person objects have descriptor starting with 'B'

Key: C, Object: An NSMutableArray where all Person objects have descriptor starting with 'C' etc...

I've tried to do this in my code below, and at the comment //POINT 1, the keys and arrays seem to match up, but at //POINT 2, when I print out the complete dictionary, all the keys come up with the same values!

So I wanted to know why th开发者_Go百科e NSMutableArray I seem to have is not being stored as I want it in the NSMutableDictionary?

- (void)buildDictionaryForIndexList {
    NSMutableDictionary *tempDict = [[[NSMutableDictionary alloc] init] autorelease];
    NSMutableArray *personsStartingWithLetter = [[NSMutableArray alloc] init];
    NSMutableArray *indexList = [[[NSMutableArray alloc] init] autorelease];
    NSInteger loopCounter = 1;
    NSString *firstLetter = [[[NSString alloc] init] autorelease];
    for (Person *v in persons) {
        firstLetter = [[v descriptor] substringWithRange:NSMakeRange(0, 1)];
        if ([indexList containsObject:firstLetter]) {
            [personsStartingWithLetter addObject:v];
            if (loopCounter == [persons count]) {
                [tempDict setObject:personsStartingWithLetter forKey:firstLetter];
            }
        } else {
            if (loopCounter > 1) {
                //POINT 1
                NSLog(@"%@",[indexList objectAtIndex:[indexList count]-1]);
                for (Person *q in personsStartingWithLetter) {
                    NSLog(@"%@",[q descriptor]);
                }
                [tempDict setObject:personsStartingWithLetter forKey:[indexList objectAtIndex:([indexList count] - 1)]];
                [personsStartingWithLetter removeAllObjects];
            }
            [indexList addObject:firstLetter];
            [personsStartingWithLetter addObject:v];
        } // else
        loopCounter++;
    } // for
     //POINT 2
    NSEnumerator *enumerator = [tempDict keyEnumerator];
    for (NSString *str in enumerator) {
        NSLog(@"%@",str);
        for (Person *c in [tempDict objectForKey:str]) {
            NSLog(@"%@",[c descriptor]);
        }
    }
    self.dictionary = tempDict;
} // buildDictionaryForIndexList

So, for example, at POINT 1 my output is:

A

Angry

Amiable

B

Belligerent

C

Cool

...

W

Wild

but at POINT 2 my output is

T

Wild

J

Wild

A

Wild

...

W

Wild


Change [tempDict setObject:personsStartingWithLetter forKey:[indexList objectAtIndex:([indexList count] - 1)]]; (just after point 1) to [tempDict setObject:[[personsStartingWithLetter copy] autorelease] forKey:[indexList objectAtIndex:([indexList count] - 1)]];. The problem is that NSDictionary copies the key, but retains the value. Therefore, if you add a mutable array to the dictionary and then change it, the array in the dictionary also changes. You need to create a non-mutable copy of the array to put in the dictionary.


The whole method is a bit overcomplicated.

- (void)buildDictionaryForIndexList 
{
    NSMutableDictionary *tempDict = [[[NSMutableDictionary alloc] init] autorelease];
    for (Person *v in persons)
    {
        NSString* firstLetter = [[v descriptor] substringWithRange:NSMakeRange(0, 1)];
        NSMutableArray* personsStartingWithLetter = tempDict [firstLetter];
        if (personsStartingWithLetter == nil)
        {
            personsStartingWithLetter = [NSMutableArray array];
            tempDict [firstLetter] = personsStartingWithLetter;
        }
        [personsStartingWithLetter addObject:v];
    } // for
    self.dictionary = tempDict;
}

You start with an empty dictionary that will contain arrays. For every person, you check whether there is a suitable array or not, and if there isn't one, you create it. So now there is an array for the person, so you add it to the array. That's all.

0

精彩评论

暂无评论...
验证码 换一张
取 消