使用map()从Dictionary数组(即JSON数组)初始化数组内联

时间:2017-05-16 05:12:29

标签: ios swift initialization

我的类可以从JSON字典

初始化
class ChildObject {
    required init?(fromDictionary dictionary: [String:Any]) { //init... }
}

现在我收到了一系列这样的词典:

// objectDictionaries = [[String:Any]]

现在我想使用map初始化我的类内联数组。我正在另一个类中初始化一个数组。

 class ParentObject {
      var children: [ChildObject]

      required init?(fromDictionary aDictionary: [String:Any]) {
            guard let childDictionaries = aDictionary["children"] as? [[String:Any]],
               let children = childDictionaries.map { ChildObject(fromDictionary: $0) }
               else { return nil }
            self.children = children
      }

 }

但是这不能编译---谁能告诉我正确的语法?我试过了forEach,但这也行不通。

在操场上我得到了

  • 在守卫之后预期
  • 匿名闭包参数未包含在 关闭
  • 预期表达
  • 支持未使用的语句块 闭合

2 个答案:

答案 0 :(得分:2)

对于这两个类,你有init?这意味着它将返回nil,所以当你映射字典数组时它会给你结果[ParentObject?][ParentObject?]它意味着数组对象是是可选的,并且您尝试将结果存储在non-optional数组中,要解决问题只需使用flatMap,因为它将ignored/reduce nil并为您提供{{1}数组对象。

non-optional

同样适用于class ParentObject { var children: [ChildObject] required init?(fromDictionary aDictionary: [String:Any]) { guard let childDictionaries = aDictionary["children"] as? [[String:Any]] else { return nil } self.children = childDictionaries.flatMap { ChildObject.init } } }

的数组
ParentObject

注意: self.parents = objectDictionaries.flatMap { ParentObject.init } 的返回类型不是map,请将其从optional中删除,就像我一样。

答案 1 :(得分:2)

map不会返回可选项,因此let children = childDictionaries.map { ChildObject(fromDictionary: $0) }不能在您的保护条款中。

另一方面,ChildObject(fromDictionary: $0)会返回一个map不支持的可选项。

您可以使用flatMap,因此将忽略无法初始化的值:

class ParentObject {
    let children: [ChildObject]

    required init?(fromDictionary aDictionary: [String:Any]) {
        guard let childDictionaries = aDictionary["children"] as? [[String:Any]],
        else { return nil }

        self.children = childDictionaries.flatMap { ChildObject(fromDictionary: $0) }

    }
}

如果必须正确初始化所有孩子,您也可以返回nil:

    required init?(fromDictionary aDictionary: [String:Any]) {
        guard let childDictionaries = aDictionary["children"] as? [[String:Any]]
        else { return nil }

        let children = childDictionaries.flatMap { ChildObject(fromDictionary: $0) }

        guard children.count == childDictionaries.count else { return nil }

        self.children = children
    }