【问题标题】:Extracting a dictionary from a multilevel array using indexPath.row使用 indexPath.row 从多级数组中提取字典
【发布时间】:2013-03-01 08:13:53
【问题描述】:

我在从声明为的多级数组中提取字典时遇到困难:

NSArray *menuItems; 看起来像这样:

Table =     (
                {
            MENUDESC = "HOME           ";
            MENUID = 1072;
            NAVIGATETO = "content.aspx?item=1072&pid=0";
            NAVIGATETO2 = "default.aspx?item=1072&pid=0";
            PARENTMENUID = "<null>";
            PROTECTED = "<null>";
            parentmenuid2 = "<null>";
        },
                {
            MENUDESC = "PRODUCTS &amp; SERVICES";
            MENUID = 1073;
            NAVIGATETO = "#";
            NAVIGATETO2 = "default.aspx?item=1073&pid=0";
            PARENTMENUID = "<null>";
            PROTECTED = "<null>";
            parentmenuid2 = "<null>";
        },
                {
            MENUDESC = "ABOUT US";
            MENUID = 1074;
            NAVIGATETO = "content.aspx?item=1074&pid=0";
            NAVIGATETO2 = "default.aspx?item=1074&pid=0";
            PARENTMENUID = "<null>";
            PROTECTED = "<null>";
            parentmenuid2 = "<null>";
        },
                {
            MENUDESC = "WHAT SETS US APART";
            MENUID = 1075;
            NAVIGATETO = "content.aspx?item=1075&pid=0";
            NAVIGATETO2 = "default.aspx?item=1075&pid=0";
            PARENTMENUID = "<null>";
            PROTECTED = "<null>";
            parentmenuid2 = "<null>";
        },
                {
            MENUDESC = "CASE STUDIES";
            MENUID = 1126;
            NAVIGATETO = "content.aspx?item=1126&pid=0";
            NAVIGATETO2 = "default.aspx?item=1126&pid=0";
            PARENTMENUID = "<null>";
            PROTECTED = "<null>";
            parentmenuid2 = "<null>";
        },
                {
            MENUDESC = "REQUEST PROPOSAL";
            MENUID = 1076;
            NAVIGATETO = "content.aspx?item=1076&pid=0";
            NAVIGATETO2 = "default.aspx?item=1076&pid=0";
            PARENTMENUID = "<null>";
            PROTECTED = "<null>";
            parentmenuid2 = "<null>";
        },
                {
            MENUDESC = CONTACT;
            MENUID = 1077;
            NAVIGATETO = "contactus.aspx?item=1077&pid=0";
            NAVIGATETO2 = "contactus.aspx?item=1077&pid=0";
            PARENTMENUID = "<null>";
            PROTECTED = "<null>";
            parentmenuid2 = "<null>";
        }
    );
}

从 JSON 创建,如下所示:

{
  "Table": [
    {
      "MENUID": 1072.0,
      "MENUDESC": "HOME           ",
      "PARENTMENUID": null,
      "NAVIGATETO": "content.aspx?item=1072&pid=0",
      "NAVIGATETO2": "default.aspx?item=1072&pid=0",
      "PROTECTED": null,
      "parentmenuid2": null
    },
    {
      "MENUID": 1073.0,
      "MENUDESC": "PRODUCTS &amp; SERVICES",
      "PARENTMENUID": null,
      "NAVIGATETO": "#",
      "NAVIGATETO2": "default.aspx?item=1073&pid=0",
      "PROTECTED": null,
      "parentmenuid2": null
    },
    {
      "MENUID": 1074.0,
      "MENUDESC": "ABOUT US",
      "PARENTMENUID": null,
      "NAVIGATETO": "content.aspx?item=1074&pid=0",
      "NAVIGATETO2": "default.aspx?item=1074&pid=0",
      "PROTECTED": null,
      "parentmenuid2": null
    },
    {
      "MENUID": 1075.0,
      "MENUDESC": "WHAT SETS US APART",
      "PARENTMENUID": null,
      "NAVIGATETO": "content.aspx?item=1075&pid=0",
      "NAVIGATETO2": "default.aspx?item=1075&pid=0",
      "PROTECTED": null,
      "parentmenuid2": null
    },
]
}

我正在研究他们使用它来提取字典的示例代码:

NSDictionary *items = [menuItems objectAtIndex:indexPath.row];

但这不起作用 - 我收到错误“发送的选择器无效”。我尝试了各种方法来访问数组中的数据。但是我发现的所有研究和答案都没有帮助。

我需要像这样从中创建 NSStrings:

NSString *text = [[menuItems objectForKey:@"Table"] objectForKey:@"MENUDESC"];
NSString *name = [[menuItems objectForKey:@"Table"] objectForKey:@"MENUID"];

【问题讨论】:

  • 在您的问题中添加 menuItem 数组的内容。
  • 为什么你认为menuItems是一个数组?
  • 它被声明为一个数组,所以我无法使用 indexForKey 访问它:
  • 我已将 menuItem 数组的内容添加到问题中。
  • 那不是数组。是具有与数组配对的单个键的字典...Table 键是您真正想要的 menuItems 的来源

标签: objective-c xcode json nsarray nsdictionary


【解决方案1】:

Objective-C 是一种相当动态的语言,因此即使您将menuItems 声明为NSArray,也不能保证它在运行时的类型。如果您从问题中反序列化 JSON 对象并将其分配给 menuItems,那么您实际上是在为其分配一个 NSDictionary 实例。请注意,JSON 的最外层符号是花括号,表示一个对象(转换为 NSDictionary),而不是方括号,表示一个数组。这个对象有一个键,Table,关联值是一个数组。

所以你需要做的是这样的:

NSArray *menuItems = JSONObject[@"Table"];

其中JSONObject 是您当前分配给menuItems 的内容。之后,menuItems 指向一个字典数组,每个字典都应该能够为您提供所需的字符串。

【讨论】:

    【解决方案2】:

    使用以下代码:

    NSLog(@"%@",[[[menuItems objectForKey:@"Table"] objectAtIndex:0] objectForKey:@"MENUDESC"]);
    
    NSLog(@"%@",[[[menuItems objectForKey:@"Table"] objectAtIndex:0] objectForKey:@"MENUID"]);
    

    这将只返回第一个数组:您也可以使用 for Loop: 获取所有值

    【讨论】:

      【解决方案3】:

      即通过 JSON 字符串发送给您的内容。 它以包含在 {} 中的键值对开始。它只有一个条目。该条目的键是“table”,它的值是一个包含多个对象的数组。数组的对象包含在 [] 中。数组中包含一组键/值对(包含在 {} 中)。

      所以每个 {} 都会被转换成一个 NSDictionary,它是键值对的合适容器。并且每个 [],甚至是空的,都将被转换为对象的 NSArray。

      您永远无法确定自己收到了什么。因此,您应该始终仔细检查接收到的值是否是 NSArray、NSDictionary、NSString 或 NSNumber。 (坦率地说,我不确定 NSDate。) 通过使用(示例)来做到这一点

      if ([myCurrentObject isKindOfClass[NSString class]]) {
        // process the data
      } else {
        // react to the error because you were expecting a string and got something else
      }
      

      这样做可以让您的应用有机会做出正确反应,即使它无法处理数据。这比您当前观察到的由未捕获的异常引起的中止要好得多。

      准备好接收空数组和字典。对于字典来说,这并不难。如果密钥不存在,objectForKey: 等将简单地返回 nil。但是当数组中没有任何对象时,objectAtIndex:0 会抛出一个无效参数异常。因此,请确保检查收到的对象的长度和存在。

      if (menuItems && [menuItems isKindOfClass[NSArray class]] && [menuItems count]) ... 
      

      会的。这首先检查 menuItem 是否不为零,然后检查它是否是 NSArray(或 NSMutableArray - 也会评估为 YES)以及数组是否包含任何对象。后者也可以通过适当的 for 循环来实现。 没有必要实际嵌套 if 语句,因为它从左侧开始计算,并且当所有条件都与逻辑 AND &amp;&amp; 连接时,将停止对找到的第一个 NO 进行计算。

      【讨论】:

        【解决方案4】:

        感谢您的回复,他们真的很有帮助。我将NSArray *menuItems; 更改为NSDictionary *menuItems;,然后这样做:

        NSDictionary *tweet = [[menuItems objectForKey:@"Table"] objectAtIndex:indexPath.row];
        NSString *text = [tweet objectForKey:@"MENUDESC"];
        NSString *name = [tweet objectForKey:@"MENUID"];
        

        效果很好,给了我这个结果:

        2013-03-02 03:00:44.396 App Test[616:c07] HOME             ID:1072
        2013-03-02 03:00:44.396 App Test[616:c07] PRODUCTS &amp; SERVICES  ID:1073
        2013-03-02 03:00:44.396 App Test[616:c07] ABOUT US  ID:1074
        2013-03-02 03:00:44.397 App Test[616:c07] WHAT SETS US APART  ID:1075
        2013-03-02 03:00:44.397 App Test[616:c07] CASE STUDIES  ID:1126
        2013-03-02 03:00:44.397 App Test[616:c07] REQUEST PROPOSAL  ID:1076
        2013-03-02 03:00:44.397 App Test[616:c07] CONTACT  ID:1077
        

        【讨论】:

        • 由于其他用户帮助了您,特别是(从您的评论来看)Hermann Klecker,因此接受解决您问题的答案是有礼貌的。我注意到您评论的其他问题表明某个用户提供了帮助,或者答案中指出的某些内容有所帮助,但您没有接受任何答案。因此,如果您不知道,我只是让您知道该网站的这一方面。如果您已经意识到接受的作用,那么请忽略此评论,我不是要强迫或唠叨,只是教育。祝你好运。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-11-04
        • 1970-01-01
        • 2020-09-06
        • 1970-01-01
        • 1970-01-01
        • 2016-10-28
        • 1970-01-01
        相关资源
        最近更新 更多