【问题标题】:How to append array on dictionary based on element exists如何基于元素附加字典数组存在
【发布时间】:2021-10-08 06:16:37
【问题描述】:

在打印 po menuList?[1]["subMenu"]

我收到以下消息

▿ Optional<Any>
  ▿ some : 1 element
    ▿ 0 : 1 element
      ▿ 0 : 2 elements
        - key : subItem
        ▿ value : 4 elements
          ▿ 0 : 7 elements
            ▿ 0 : 2 elements
              - key : permission
              - value : access
            ▿ 1 : 2 elements
              - key : title
              - value : Create
            ▿ 2 : 2 elements
              - key : bar
              - value : sidebar
            ▿ 3 : 2 elements
              - key : isNotify
              - value : 0
            ▿ 4 : 2 elements
              - key : link
              - value : linker
            ▿ 5 : 2 elements
              - key : path
              - value : /dashboard
            ▿ 6 : 2 elements
              - key : icon
              - value : add

尝试根据条件提取menuList?[i]["subMenu"]["subItem"],如果侧子项中存在值,则附加到数组,否则不添加。

少数情况 ["subItem"] 可能有 0 个元素

    if let permissionList =  MenuList?[i]["subMenu"] {
        let subMenu =  (permissionList as AnyObject)
        if subMenu.count > 0 {
            for j in 0..<subMenu.count{
             let subItem =  subMenu["subItem"]
            }
        }

对我来说它的回报为零

在尝试 subMenu[0] 错误:“下标(_:)”的使用不明确 子菜单[0]

【问题讨论】:

  • 你试过什么?结果与您的预期有何不同?
  • @jnpdx 我更新了我尝试过的问题。
  • 在您打印的示例数据中,subItem 仅出现在两级数组之后。现在,您似乎只深了一层。
  • @kiran menuList 的类型是什么?这将有助于解决这个问题。
  • @George_E var menuList: [[String: Any]]?它的字典数组

标签: ios arrays swift dictionary


【解决方案1】:

这是 George 函数的一个变体,使用映射操作而不是手动循环来表示:

func menuResult() -> [String] {
    // FIXME: Why is this even optional in the first place?
    guard let menuList = menuList else { return [] }

    return menuList.compactMap { menu -> [String] in
        guard let subMenu = menu["subMenu"] as? [String: String] else { return nil }
        return subMenu["subItem"]
    }
}

【讨论】:

  • 或简单地(menu["subMenu"] as? [String: String])?["subItem"]。单行也是首选,因为它有利于类型推断。不确定,但menuList?.compactMap { ($0["subMenu"] as? [String: String])?["subItem"] } ?? [] 应该可以工作
  • @LeoDabus 是的,虽然我避免走那么远,因为调试真的很痛苦。也许现在 Xcode 允许您在表达式中放置断点,这样的表达式可能更适合使用
【解决方案2】:

例如menuData 是这样的:

let menuList: [[String: Any]]? = [
    ["abc": [
        "123": "test1",
        "456": "test2"
    ]],
    ["def": [
        "789": "test3",
        "101112": "test4"
    ]],
    ["subMenu": [
        "subItem": "Other correct path" // <- subMenu[2]["subMenu"]["subItem"]
    ]],
    ["subMenu": [
        "otherItem": "WRONG",
        "subItem": "CORRECT" // <- subMenu[3]["subMenu"]["subItem"]
    ]]
]

获取menuData数组menuData[i]["subMenu"]["subItem"]中所有项目的代码:

func menuResult() -> [String] {
    // menuList can't start nil
    guard let menuList = menuList else { return [] }
    var result = [String]()

    // Iterate every element of menuList
    for i in menuList.indices {
        // Get 'subMenu' dictionary if it exists
        if let subMenu = menuList[i]["subMenu"] as? [String: String] {
            // Get 'subItem' dictionary if it exists
            if let subItem = subMenu["subItem"] {
                // Store value at this path
                result.append(subItem)
            }
        }
    }

    return result
}
print(menuResult())
// Prints: ["Other correct path", "CORRECT"]

【讨论】:

  • 您的for 循环可以替换为简单的compactMap
  • 当代码字面意思是 return result 时,我是否还建议删除像 // Return result 这样的注释。评论内容应该有一个非常高的标准。
  • 如果您有兴趣,我有一些可能对这段代码有益的提示/技巧。不过,在 SE 聊天中讨论它们会更容易
  • @Alexander Tbh,我想我只是对这里的 cmets 有点得意了? 回想起来肯定有很多低效率的地方(比如索引,不是真的需要P
  • 我不使用推特,但我很乐意在这里聊天。如果我们多次来回发送垃圾邮件,则应提供聊天室链接
猜你喜欢
  • 2015-08-04
  • 1970-01-01
  • 2020-02-14
  • 2015-12-11
  • 1970-01-01
  • 2015-02-03
  • 2019-01-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多