kiran
kiran

Reputation: 4409

How to append array on dictionary based on element exists

On print po menuList?[1]["subMenu"]

I got below message

▿ 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

Trying to extract menuList?[i]["subMenu"]["subItem"] based on condition if value exist in side subItem then append to array else not.

few cases ["subItem"] may have 0 elements

    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"]
            }
        }

Its return nil for me

On try subMenu[0] error: ambiguous use of 'subscript(_:)' subMenu[0]

Upvotes: 0

Views: 135

Answers (2)

George
George

Reputation: 30421

For example menuData like this:

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"]
    ]]
]

Code to get all items in the menuData array at 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"]

Upvotes: 0

Alexander
Alexander

Reputation: 63321

Here's a variant of George's function, expressing using a map operation rather than a hand-rolled loop:

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"]
    }
}

Upvotes: 1

Related Questions