Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS Build a Photo Browser iPhone App UIKit Dynamics Extra Credit

Remove NSMutableDictionary entry

Hi Treehousers,

I am looking to remove entries from a NSDictionary by making a mutable copy of it and scanning the keys that contain a specific string.

Namely, @"anonymousUser".

I implemented the following code using an "overarching" NSSet and using the removeObjectsForKeys method.

But it looks like I have an issue with the way I use the rangeOfString method that helps me scan the content of the dictionary and identify the entries to clean up.

Here is the error message and my code: https://www.dropbox.com/s/qfnb4vhzny9bi6y/Range_Of_String.png

Any help much appreciated.

12 Answers

Kerde: Extremely concise solution on stackoverflow. I tested it and it works great.

May be worth a look: http://stackoverflow.com/questions/25292741/remove-entries-from-nsmutabledictionary-based-on-match-on-nsstring-value/25293435#25293435

Again, thanks for your help. If you are open to it, let's connect on LinkedIn for future synergies.

A bientot :)

Ah okay, I see what he did. You can check my profile for my linkedin info. Glad you got it working.

Hmm, not sure you need to use removeObjectForKeys

Okay so ultimately after you have your mutable dictionary you want to remove all @"anonymousUser" from the dictionary. Isn't @"anonymousUser" only under the profile_picture key?

I think the API uses an array of dictionaries. So you could loop through the array :

[[array objectAtIndex:i] objectForKey:@"profile_picture"]

Check the value and using the answer I gave in the other post, you can change it.

Hmmm... I realize this topic of removing an entry from a mutable dictionary is not well documented on net.

If I go for your method, I don't see how I can remove the entry all together. I don't want to replace the string, remove the entry without deleting all values referenced by the associated key.

Isn't there a "removeObject:" method in some way?

Would value seeing sample code.

Merci!

Okay I understand what you're trying to do alot better now. You want to remove the entry from the dictionary if it has a certain keyword:

    NSMutableDictionary * myDictionary =[ NSMutableDictionary dictionary];
    [myDictionary setObject:@"http://www.sdsdfsdfsdf.com/anonymousUser" forKey:@"profile" ];
    [myDictionary setObject:@"https://teamtreehouse.com/forum/remove-nsmutabledictionary-entry" forKey:@"random"];
    [myDictionary setObject:@"https://google.com" forKey:@"someUrl" ];
    [myDictionary setObject:@"test" forKey:@"someValue"];
    [myDictionary setObject:@"anonymousUser.png/blahblahblah" forKey:@"anotherValue"];


    NSArray*keys=[myDictionary allKeys]; //get all the keys

    for (int i = 0; i<[keys count]; i++) {

        if ([[myDictionary objectForKey:[keys objectAtIndex:i]] isKindOfClass:[NSString class]]) {
         //if its an NSString - don't want an exception if its another type of object

             if ([[myDictionary objectForKey:[keys objectAtIndex:i]] rangeOfString:@"anonymousUser"].location != NSNotFound) {

                 //if object has the key word im looking for
                 [myDictionary removeObjectForKey:[keys objectAtIndex:i]]; //remove the key
             }
        }
    }

This will remove any entry that has anonymousUser as a value

Hi Kerde,

Thank you so much for your help, and patience on this. This is much appreciated.

I implemented your code after creating a mutable copy of the NSDictionary that I get back from instagram (responseDictionary).

However, here is what I get after logging the results: https://www.dropbox.com/s/8erj76yxlrw8nq2/Still_Anonymous_After_CleanUp.png

As you can see, my anonymous entries are still there.

I am confident it's a minor tweak to get to the desired result.

Any other ideas?

Have a great day!

:)

Can you put a break point and see whats happening as it goes through the loop. Also send a screenshot of the dictionary object.

Sure!

It looks like I am going to learn something new soon. Great!

Here is a log of k1 which I defined as the count (of entries) in the NSDictionary delegate that I receive back from Instagram. For some strange reasons you can see that it is equal to 3: https://www.dropbox.com/s/ksbc9pabybn0pb4/k1.png

Then I do the mutable copy of the NSDictionary delegate I get back from Instagram and store it into a NSMutableDictionary to complete the AnonymousUser lookup and cleanup.

I call k2 the number of entries in this dictionary, not surprisingly, before cleanup (the for loop) k2 is equal to 3: https://www.dropbox.com/s/eqw9d75zzly1icf/k2_before.png

After cleanup, it's still equal to 3: https://www.dropbox.com/s/rals66t84yju6fb/k2%28after%29%3D3but_friendsCount%3D191.png

Two things:

It should not be equal to 3 but to 191 which is the count of the "friends" NSDictionary where I store the cleanup version of the NSMutableDictionary. Since the for loop doesn't seem to start (NSLogs in that loop do not show up in my console for a reason I don't understand since we should have at least 3 loops since k2=3). When logging self.friends, set with the result of the cleanup, and looking at [self.friends count], number of entries in the friends NSDictionary... I get 191! (LOL)

There is clearly something new I am going to learn here. Not so sure what this is related to, most likely an obvious mistake on my end.

Thanks again for your help.

:)

k2 would still be 3. Where are you updating the k2 value after cleanup?

Also I think the issue is with the for loop using k2.

Shouldnt it be

NSUInteger * k2 = [keys count]; 

E.g 5 keys, loop 5 times, and at key position i, check if value is equal to anonymous etc

Well, the number of loops should be equal to the number of entries, and not keys, in the dictionary.

For each entry, we need to scrub against the "anonymousUser" NSString and remove that entry if there is a match.

What seems weird to me is that even with a number of loops, erroneous at 3 (k2 should be equal to 191, the numbers of entries I have in the NSDictionary), the loop doesn't start which seems to indicate that none of the keys in the dictionary is of type NSString. And that is not the case since most keys are NSStrings...

Well, I'll keep trying to figure that one out. Thanks again for your great help Kerde. :)

What value do you get back when you use the [keys count] ?

I am thinking of opening something on stackoverflow

@Kerde: for [keys count] I get 3.

hmm well okay, sorry man, not too sure what the issue is. Unless you want to send me a barebones copy of your project to look at myself. Or send me a copy of the instagram api response and I will create a new project and try to get it working. Shouldn't take more than 5 minutes. Arsene Lavaux

Hi Kerde: Here is the structure of the NSDictionary I get back from instagram api:

{
        bio = "xxxbioStringxxx";
        "full_name" = "xxxnameStringxxx";
        id = 1234567890;
        "profile_picture" = "http://photos-c.ak.instagram.com/hphotos-ak-xpa1/stringidpicture.jpg";
        username = xxxusernamexxx;
        website = "http://xxx.blogspot.com";
    },

If you can find the time. I appreciate.