如何在 Objective-C iphone sdk 中迭代嵌套字典

发布于 2024-09-10 19:34:50 字数 773 浏览 7 评论 0原文

您好,我有一个 json 字符串,已通过 JSON 框架转换为字典,我需要提取其内容。我怎样才能迭代到嵌套字典?我已经有了这段代码,可以让我查看字典:

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

有人可以提供一个示例,说明如何在不使用键名的情况下到达 dic 的所有级别吗?

dic的结果结构是这样的: http://www.freeimagehosting.net/uploads/ e7c020d697.png

替代文本 http://www.freeimagehosting.net/uploads/e7c020d697 .png

谢谢

ldj

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

难以启齿的温柔 2024-09-17 19:34:54

我尝试过递归,希望这能有所帮助。
PS 这将返回该键的第一次出现。

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

I have tried recursion and hope this could help.
P.S. This will return the first occurrence of the key.

+(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;
}
提笔书几行 2024-09-17 19:34:53

我确信您现在已经解决了这个问题,但我发现编写一个递归实用程序类函数来递归记录字典的每个键很方便:

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

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;
}
浅听莫相离 2024-09-17 19:34:53

类别的标题:

#import <Foundation/Foundation.h>

@interface NSDictionary(Find)

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

@end

正文:用法

#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

/验证:

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

}

The header of the category:

#import <Foundation/Foundation.h>

@interface NSDictionary(Find)

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

@end

The body:

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

}

彼岸花ソ最美的依靠 2024-09-17 19:34:52

您可能必须尝试递归函数。

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

这将列出所有键及其级别。

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.

秋叶绚丽 2024-09-17 19:34:52

尝试



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

希望有帮助。

编辑:
我不确定我是否理解你的结构正确,但我假设你的字典中有一些值,它们又是字典。
如果你想通过位于另一个字典内部的字典进行交互,你可以这样做:


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

当然,如果你知道所需字典的特定键,你可以检查它而不是检查该值是否是字典。但也许在这两种情况下检查一下并不是一个坏主意......

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...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文