2010-07-23 4 views
5

Salut J'ai une chaîne json convertie en désinsérant le cadre JSON dans un dictionnaire et j'ai besoin d'extraire son contenu. Comment pourrais-je itérer les dictionnaires imbriqués? J'ai déjà ce code qui me permet de voir le dictionnaire:comment itérer des dictionnaires imbriqués dans l'objectif-c iphone sdk

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; 
} 

Quelqu'un pourrait-il fournir un échantillon sur la façon de se rendre à tous les niveaux de la dic ne pas utiliser le nom des clés?

La structure de résultat de la CIVD est comme ceci: http://www.freeimagehosting.net/uploads/e7c020d697.png

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

grâce

LDJ

+0

Désolé, je ne vous suis pas. – ldj

Répondre

5

Essayez



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

Espoir qui a aidé. Je ne suis pas sûr si je comprends votre structure correcte, mais je suppose que vous avez des valeurs dans votre dictionnaire qui sont encore des dictionnaires. si vous voulez interate par un dictionairy qui est situé dans un autre que vous pourrait le faire comme ceci:


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]) { 
      ... 
     } 
    } 
} 

de couse si vous connaissez la clé spécifique à votre dictionairy désirée, vous pouvez vérifier qu'au lieu de vérifier si la valeur est dict. Mais peut-être que ce n'est pas une mauvaise idée de vérifier que dans les deux cas ...

+0

Tobi Merci, Oui ce code fait la même chose que j'ai déjà. Je suis plus intéressé par un exemple qui me montre comment je pourrais obtenir toutes les clés sous Arts (Antiquités, Verrerie) et avec celles-ci obtenir l'entrée pour business_name sous propriétés. Pouvez-vous modifier votre extrait de code pour servir cet objectif? Merci – ldj

+0

Salut, ive édité ma réponse ci-dessus, est-ce cela que vous ment? – Tobi

9

Vous devrez probablement essayer la fonction récursive.

-(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 
     } 
    } 
} 

Ceci affichera toutes les clés et leur niveau.

1

Je suis sûr que vous avez résolu ce à ce moment, mais je l'ai trouvé commode d'écrire une fonction de classe utilitaire récursif qui se connecte de manière récursive toutes les clés d'un dictionnaire:

/** 
* 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; 
} 
0

J'ai essayé récursivité et d'espoir Cela pourrait aider.
P.S. Cela retournera la première occurrence de la clé.

+(id)getValue:(NSDictionary*)aDictionary forKey:(NSString *)aKey { 
    id finalValue = nil; 
    for (id key in [aDictionary allKeys]) { 
     id value = aDictionary[key]; 
     if (value != nil && [key isEqualToString:aKey]) { 
     finalValue = value; 
     break; 
     } 
     else if ([value isKindOfClass:[NSDictionary class]]) { 
     finalValue = [[self class] getValue:value forKey:aKey]; 
     } 
    } 
    return finalValue; 
} 
0

L'en-tête de la catégorie:

#import <Foundation/Foundation.h> 

@interface NSDictionary(Find) 

-(id) findflat:(NSString*)keyToFind; 

@end 

Le corps:

#import "NSDictionary+Find.h" 

@implementation NSDictionary(Find) 

-(id) findflat:(NSString*)keyToFind{ 

    if([self objectForKey:keyToFind]) 
     return self[keyToFind]; 

    for(id key in self) 
     if([[self objectForKey:key] isKindOfClass:[NSDictionary class]]) 
      return [[self objectForKey:key] findflat:keyToFind]; 


    return nil; 
} 

@end 

Utilisation/Validation:

- (void)testExample { 
// This is an example of a functional test case. 
// Use XCTAssert and related functions to verify your tests produce the correct results. 

NSDictionary *dic = @{}; 
XCTAssertNil([dic findflat:@"url"]); 

dic = @{@"url":@"http://"}; 
XCTAssertEqual([dic findflat:@"url"],@"http://"); 

dic = @{@"other":@4}; 
XCTAssertNil([dic findflat:@"url"]); 

dic = @{@"other":@4,@"url":@"http://"}; 
XCTAssertEqual([dic findflat:@"url"],@"http://"); 

dic = @{@"other":@4,@"sd":@"sdf"}; 
XCTAssertNil([dic findflat:@"url"]); 

dic = @{@"other":@4,@"dic":@{@"url":@"http://"}}; 
XCTAssertEqual([dic findflat:@"url"],@"http://"); 

dic = @{@"other":@4,@"dic":@{@"sd":@2,@"url":@"http://"}}; 
XCTAssertEqual([dic findflat:@"url"],@"http://"); 

dic = @{@"other":@4,@"dic":@{}}; 
XCTAssertNil([dic findflat:@"url"]); 

dic = @{@"other":@4,@"dic":@{@"dic":@{@"sd":@2,@"url":@"http://"}}}; 
XCTAssertEqual([dic findflat:@"url"],@"http://"); 

}

Questions connexes