2010-07-23 13 views
5

Hola Tengo una cadena json convertida usando el marco JSON en un diccionario y necesito extraer su contenido. ¿Cómo podría iterar a los diccionarios anidados? Ya tengo el código que me permite ver el diccionario:cómo iterar diccionarios anidados en target-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; 
} 

Podría alguien proporcionar una muestra de cómo llegar a todos los niveles de la DIC no usar el nombre de las teclas?

La estructura de resultados de la CID es la siguiente: http://www.freeimagehosting.net/uploads/e7c020d697.png

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

gracias

LDJ

+0

Perdón, no te sigo. – ldj

Respuesta

5

Trate



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

esperanza de que ayudó.

EDIT: no estoy seguro de si entiendo tu estructura correcta, pero supongo que tienes algunos valores en tu dictionairy que son nuevamente dictionairies. si quieres Interate a través de un dictionairy que se encuentra dentro de otro que podría hacerlo de esta manera:


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 conoce la clave específica para su dictionairy desea, puede comprobar que en vez de comprobar si el valor es un dict Pero tal vez no es una mala idea comprobar que en ambos casos ...

+0

Tobi Gracias, sí, este código hace lo mismo que yo ya tengo. Estoy más interesado en un ejemplo que me muestra cómo podría obtener todas las claves en Artes (Antigüedades, Cristalería) y obtener la entrada para nombre_empresa en propiedades. ¿Puedes editar tu fragmento de código para cumplir este objetivo? Gracias – ldj

+0

Hola, he editado mi respuesta anterior, ¿es eso lo que mencionas? – Tobi

9

Probablemente tengas que probar la función recursiva.

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

esto listará todas las claves y su nivel.

1

Estoy seguro de que han resuelto este en este momento, pero me pareció conveniente escribir una función recursiva que clase de utilidad de forma recursiva registra cada clave de un diccionario:

/** 
* 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

He tratado de recursividad y la esperanza esto podría ayudar.
P.S. Esto devolverá la primera aparición de la clave.

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

La cabecera de la categoría:

#import <Foundation/Foundation.h> 

@interface NSDictionary(Find) 

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

@end 

El cuerpo:

#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 

Uso/Validación:

- (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://"); 

}