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

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

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

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

【问题讨论】:

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

标签: iphone objective-c cocoa-touch ios nsdictionary


【解决方案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 并链接到最近对类似主题的讨论非常有帮助。
  • 我认为答案部分旨在解决原始海报问题的响应。您应该发布指向其他主题的链接作为评论,而不是答案。另外,我很少投反对票:stackoverflow.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);
    

    【讨论】:

      猜你喜欢
      • 2011-12-16
      • 2020-04-17
      • 1970-01-01
      • 2022-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多