WebOrCode
WebOrCode

Reputation: 7294

Loop thru array of dictionary and add new key to each dictionary in iOS

I found something strange today in iOS, I solved it, but I would like to ask is there better (more iOS) solution.

What I wanted to do is:
Loop thru array of dictionary and add new key to each dictionary in iOS

This is code (this is not my original code, it is more complicated, but I done this code for illustrating the point easy):

- (void)testLoopThruArrayOfDictionaryAndAddNewKeyToEachDictionary
{
    NSMutableArray* a = [[NSMutableArray alloc] init];
    [a addObjectsFromArray:@[ @{@"one": @11, @"two": @12, } ]];
    [a addObjectsFromArray:@[ @{@"one": @21, @"two": @22, } ]];

    NSLog(@"%@", a);

    /*
    // NOT WORKING
    for (NSMutableDictionary* dict in a)
    {
        // -[__NSDictionaryI setObject:forKey:]: unrecognized selector sent to instance 0x8b5bca0
        [dict setObject:@3 forKey:@"three"]; 
    }
    */

    // THIS IS WORKING
    for (int i=0; i<[a count]; i++)
    {
        // make tmp copy
        NSMutableDictionary *tmpA = [a[i] mutableCopy];

        [tmpA setObject:@3 forKey:@"three"];

        // put to new value, because I use this [allValidMoves[i] mutableCopy];
        a[i] = tmpA;
    }

    NSLog(@"%@", a);
}

As you can see second loop is working, but I need to make copy of array and then put that copy back to array.
First loop was returning NSDictionary even when I asked for NSMutableDictionary.

QUESTION
1. Is it possible to do this with less code ?
2. Are there some side effect to my implementation ?

Upvotes: 1

Views: 1567

Answers (1)

trojanfoe
trojanfoe

Reputation: 122391

First ensure the array holds NSMutableDictionary objects, and not NSDictionary objects to avoid the need to convert while iterating:

NSMutableArray* a = [ @[ [ @{@"one": @11, @"two": @12, } mutableCopy], [ @{@"one": @21, @"two": @22, } mutableCopy] ] mutableCopy ];

(I don't like that code, use this instead):

NSMutableArray *a = [NSMutableArray new];
[a addObject:[NSMutableDictionary dictionaryWithObjectsAndKeys:@(11), @"one", @(12), @"two", nil]];
[a addObject:[NSMutableDictionary dictionaryWithObjectsAndKeys:@(21), @"one", @(22), @"two", nil]];

And then use:

[a enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    NSMutableDictionary *dict = (NSMutableDictionary *)obj;
    dict[@"three"] = @(3);
}];

Upvotes: 6

Related Questions