在 NSDictionary 中达到最深的儿童级别

Posted

技术标签:

【中文标题】在 NSDictionary 中达到最深的儿童级别【英文标题】:Reaching to deepest child level in NSDictionary 【发布时间】:2011-05-14 17:02:45 【问题描述】:

我有一个 NSDictionary 对象,其中包含深层结构,例如包含包含字典的进一步数组的数组...

我想在层次结构中向下获取一个对象。是否有任何直接索引方法可以使用键名或其他方式获取它们?

多次调用 objectForKey 方法以达到最深的子级是很痛苦的。

【问题讨论】:

嗯,你到底期待什么?我的意思是你可以用递归遍历这样一个多维数据结构。更精确地了解存储在结构中的内容。索引是什么意思?除了数组和字典之外,存储在结构中的所有对象是否都有唯一标识符? iPhone - Changing a sub-sub-sub NSMutableDictionary value的可能重复 我有一本大字典,里面有很深的层次结构...我想阅读它并创建另一个结构相同但在阅读源字典时进行一些修改的字典。 【参考方案1】:

如果您只使用字典,并且字典中的键始终是字符串,则可以使用key-value coding 遍历多个级别的字典:

id someObject = [mainDictionary valueForKey:@"apple.pear.orange.bear"];

这相当于:

NSDictionary *level2Dict = [mainDictionary objectForKey:@"apple"];
NSDictionary *level3Dict = [level2Dict objectForKey:@"pear"];
NSDictionary *level4Dict = [level3Dict objectForKey:@"orange"];
id someObject = [level4Dict objectForKey:@"bear"];

但是,如果您还混合了数组,这就不那么方便了。有关此主题的更多信息,请参阅 this recent SO discussion。

【讨论】:

OP 已声明它确实包含数组,因此此响应虽然相关,但并未回答问题。 @coneybeare,您是否对每个不能完全回答问题的答案投反对票?我认为指出 KVC 并链接到最近对类似主题的讨论非常有帮助。 我认为答案部分旨在解决原始海报问题的响应。您应该发布指向其他主题的链接作为评论,而不是答案。另外,我很少投反对票:***.com/users/69634/coneybeare 548 上,53 下。 谢谢@Caleb,这就是我要找的。​​span> 【参考方案2】:

对于包含数组的结构,没有内置方法可以执行以下操作:

[dict objectForKey:@"[level1][level2][level3]"]

话虽如此,内置的任何东西都只是 Apple 某人编写的代码,您也可以这样做。

编写一个辅助类,它会根据您创建的键连接方案为您完成此操作,然后调用它。它将保存代码重复。

【讨论】:

【参考方案3】:
//
//  NSDictionary+Path.h
//
//  Created by Wu Li-chih on 10/3/12.
//  Copyright (c) 2012 Wu Li-chih. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface NSDictionary (Path)
- (id) objectForPath:(NSArray*)aKeyPath;
@end

//
//  NSDictionary+Path.m
//
//  Created by Wu Li-chih on 10/3/12.
//  Copyright (c) 2012 Wu Li-chih. All rights reserved.
//

#import "NSDictionary+Path.h"

@implementation NSDictionary (Path)

- (id) objectForPath:(NSArray*)aKeyPath

    if([d isKindOfClass:[NSDictionary class]])
        d = [d objectForKey:aKey];
    else if([d isKindOfClass:[NSArray class]])
        d = [d objectAtIndex:[aKey integerValue]];
    else
        return nil;
    if(d == nil)
        return nil;



@end

// example
id v = [dict objectForPath:@[@"root", @"sub", @"target_node"]];

NSDictionary *a = @ @"aaa" : @ @"bbb": @[@123, @456, @@"ccc": @"result"];
id r = [a objectForPath:@[@"aaa", @"bbb", @2, @"ccc"]];
STAssertTrue([r isEqualToString:@"result"], nil);
r = [a objectForPath:@[@"aaa", @"bbb", @0, @"ccc"]];
STAssertNil(r, nil);

【讨论】:

以上是关于在 NSDictionary 中达到最深的儿童级别的主要内容,如果未能解决你的问题,请参考以下文章

计算深度或嵌套列表的最深级别

在 MySQL 中达到平均水平

10 $digest() 迭代在 IE 中达到错误。不知道为啥

无法在类的结构中达到内存错误

防止在 Android 中达到 65k 方法

Http 请求失败:在 Azure 逻辑应用中达到超时