Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to iterate nested dictionaries in objective-c iphone sdk

Hi I have a json string converted unsing the JSON framework into a dictionary and I need to extract its content. How could I iterate to the nested dictionaries? I have already this code that allows me to see the dictionary:

NSDictionary *results = [responseString JSONValue]; 
NSMutableArray *catArray = [NSMutableArray array];

for (id key in results) {
    NSLog(@"key: %@, value: %@", key, [results objectForKey:key]);
    [catArray addObject:key];
    NSString *cat = key;
}

Could someone provide a sample on how to get to all the levels of the dic not using the name of the keys?

The result structure of the dic is like this: http://www.freeimagehosting.net/uploads/e7c020d697.png

alt text http://www.freeimagehosting.net/uploads/e7c020d697.png

thanks

ldj

like image 536
ldj Avatar asked Jul 23 '10 16:07

ldj


3 Answers

You probably have to try recursive function.

-(void)recurse:(NSDictionary *)dict counter: (int*) i parent:(NSString *) parent{
    for (NSString* key in [dict allKeys]) {
        id value = [dict objectForKey:key];
        NSLog(@"%@ -> %@", parent, key);
        if ([value isKindOfClass:[NSDictionary class]]) {
            i++;
            NSDictionary* newDict = (NSDictionary*)value;
            [self recurse:newDict counter:i parent:key];
            i--;
        } else {
            //Do smthg
        }
    }
}

this will list all keys and its level.

like image 194
Denis Mikhaylov Avatar answered Oct 04 '22 22:10

Denis Mikhaylov


Try



for ((id) key in [results allKeys]) {
    NSLog(@"key: %@, value: %@", key, [results objectForKey:key]);
    [catArray addObject:key];
    NSString *cat = key;
}

Hope that helped.

EDIT: i'm not sure if i understand your structure correct, but i'm asuming you have some values in your dictionairy which are again dictionairies. if you want to interate through a dictionairy which is located inside another one you could do it like this:


for ((id) key in [results allKeys]) {
    id value = [results objectForKey:key];
    if ([value isKindOfClass:[NSDictionary class]]) {
        NSDictionary* newDict = (NSDictionary*)value;
        for ((id) subKey in [newDict allKeys]) {
            ...
        }
    }
}

Of couse if you know the specific key to your desired dictionairy, you can check for that instead of checking if the value is a dict. But maybe it's not a bad idea to check that in both cases...

like image 37
Tobi Avatar answered Oct 04 '22 22:10

Tobi


I'm sure you have solved this at this point, but I found it convenient to write a recursive utility class function that recursively logs every key of a dictionary:

/**
 *  Recursively logs the keys and values of each object in the dictionary,
 *  along with the class of the value.
 *
 *  @param dict The dictionary to inspect
 */
+ (void)logDictionaryKeys:(NSDictionary*)dict {
    for (id key in dict) {
        if ([dict[key] isKindOfClass:[NSDictionary class]]) {
            [self logDictionaryKeys:dict[key]];
        }else {
            NSLog(@"Key: %@", key);
            NSLog(@"Value: %@ (%@)", dict[key], [dict[key] class]);
        }
    }

    return;
}
like image 20
HighFlyingFantasy Avatar answered Oct 04 '22 22:10

HighFlyingFantasy