Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

larswik

macrumors 68000
Original poster
Sep 8, 2006
1,552
11
I have a project that has a few NSMutableDict nested PROJECTS Dict / LOCATIONS Dict / ITEM_NAME Dict / ITEM_PARTS Array.

Each ITEM_NAME has a KEY for example @"Box1" and Box1 has a VALUE that is an array with the parts list of what is in that box.

I am wondering if there is an easier way to get the keys from ITEM_NAME? Curently I do something like this
Code:
NSMutableDict *projectDict = [NSMutDict alloc] init from my plist file];
NSMutableDict *locationDict = [NSMutDict initWithDict:[projDict objectForKey@"location"]];
NSMutableDict *ItemsDict = [NSMutDict initWithDict:[locationDict objectForKey@"items"]];
NSArray *itemsArray = [itemsDict allKeys];

Is there a shortcut that I can nest it to get the keys out without having to create all of these Dict objects as I dig for the one that I want? Something that can be done on 1 line?
 
First, your misspellings indicate you typed this code sample in rather cut and paste from real source. This isn't good practice from the requester. That'd be you. If someone wanted to build and test with your code, they'd have to fix your errors. They shouldn't have to.

Because of all the embedding I don't see a real shortcut. Also, to me it looks like you are allocating space you don't need to. Perhaps these alternatives would be helpful.

Code:
NSMutableDict *projectDict = [NSMutableDict alloc] init from my plist file];
NSMutableDict *locationDict = [projectDict objectForKey@"location"]; // <-- Return value is an id, so don't think you need to allocate.
NSMutableDict *ItemsDict = [locationDict objectForKey@"items"]; // <-- Return value is an id, so don't think you need to allocate.
NSArray *itemsKeyArray = [itemsDict allKeys]; // <-- Returns a new array containing the dictionary’s keys. Possible need to retain.

OR

NSMutableDict *projectDict = [NSMutableDict alloc] init from my plist file];
NSArray *itemsKeyArray = [[[projectDict objectForKey@"location"] objectForKey@"items"] allKeys]; <-- One line for your three.


If you are actually wanting to iterate through that keys array then fast enumeration like this may be helpful;

Code:
for (NSString * partsKey in itemsKeyArray) {
        NSLog(@"part: %@", partsKey);
}
 
First, your misspellings indicate you typed this code sample in rather cut and paste from real source.

Ya it was for more of a suto code explaining the process of unpacking nested Dicts.

NSArray *itemsKeyArray = [[[projectDict objectForKey@"location"] objectForKey@"items"] allKeys]; <-- One line for your three.

This is what I was thinking of. So even if I had 10 NSDicts embedded for example I could use the objectForKey to keep reaching into the next embeddd dict till I find the dict I want and then grab the allKeys. This is the one line I was hoping to discover. Thanks!

Also, as a side note, when you said don't need to alocate because the return value is an ID. If I understand that right since it already exits in memory I just need to create a pointer that points to the existing memory location of that NSDict object. By allocating memory like I did I create a second memory location that I copy that NSdict too which is not needed? Did I get that?

Thanks again!
 
This is what I was thinking of. So even if I had 10 NSDicts embedded for example I could use the objectForKey to keep reaching into the next embeddd dict till I find the dict I want and then grab the allKeys. This is the one line I was hoping to discover. Thanks!

In a super deep nested dictionary I could foresee using a for loop to dig down deep. You'd supply an ordered array of keys and go at it.

Also, as a side note, when you said don't need to alocate because the return value is an ID. If I understand that right since it already exits in memory I just need to create a pointer that points to the existing memory location of that NSDict object. By allocating memory like I did I create a second memory location that I copy that NSdict too which is not needed? Did I get that?

You got it. So if locationDict or ItemsDict was an instance variable and you used the property keyword to define them, you'd use the assign attribute instead of copy, retain, or strong.

BTW ItemsDict is not named properly. It's bad form to start variable names with upper case characters.
 
You'd supply an ordered array of keys and go at it.

Click! I see this approach now thanks.

BTW ItemsDict is not named properly.

Yep, that was a typo. Classes are the only thing that I have used uppercase for. Sorry.

Thanks for your help.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.