2010-07-23 9 views
5

Witam Mam konwertowane ciągi json unsing ram JSON do słownika i muszę wyodrębnić jego zawartość. Jak mogę iterować do zagnieżdżonych słowników? Mam już ten kod, który pozwala mi zobaczyć słownika:jak iterować zagnieżdżone słowniki w celu-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; 
} 

Może ktoś dostarczyć próbkę, w jaki sposób dostać się do wszystkich poziomów DIC nie używając nazwy kluczy?

Struktura wynikiem DIC jest tak: http://www.freeimagehosting.net/uploads/e7c020d697.png

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

dzięki

ldj

+0

Przepraszam, że nie podążam za tobą. – ldj

Odpowiedz

5

Spróbuj



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

nadzieję, że pomogło.

EDYTOWANIE: Nie jestem pewien, czy rozumiem twoją strukturę poprawnie, ale przypuszczam, że masz pewne wartości w twoim dictionairy, które są znowu dictionairies. jeśli chcesz interate przez dictionairy, który znajduje się wewnątrz innego można zrobić to tak:


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

couse jeśli znasz konkretny klucz do żądanej dictionairy, można sprawdzić, że zamiast sprawdzania jeśli wartość jest dict. Ale może nie jest złym pomysłem sprawdzenie, czy w obu przypadkach ...

+0

Tobi Dzięki, tak ten kod robi to samo, co już mam. Bardziej interesuje mnie przykład, który pokazuje mi, jak mogłem zdobyć wszystkie klucze w Arts (Antiques, Glassware) iz tymi otrzymam wpis dla business_name w ramach właściwości. Czy możesz edytować swój fragment kodu, aby służyć temu celowi? Dzięki – ldj

+0

cześć, edytowałem moją odpowiedź powyżej, jest to, co masz? – Tobi

9

Prawdopodobnie musisz wypróbować funkcję rekursywną.

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

spowoduje wyświetlenie listy wszystkich kluczy i ich poziomu.

1

Jestem pewien, że rozwiązali to w tym momencie, ale uważam, że to wygodne, aby napisać klasy funkcji rekurencyjnej narzędziowy, który rejestruje każde rekurencyjnie klucz słownika:

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

Próbowałem rekurencji i nadziei to mogłoby pomóc.
P.S. Spowoduje to zwrócenie pierwszego wystąpienia klucza.

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

Nagłówek kategorii:

#import <Foundation/Foundation.h> 

@interface NSDictionary(Find) 

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

@end 

Korpus:

#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 

Usage/Walidacja:

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

}