2016-05-08 11 views
3
でFlatMapし、init

構造体スウィフト

私はdotSwift 2016デモにクリスEdihoffによって与えられたデモでコードを再作成してみました。ここにコードがあります。

struct List { 
    let name:String 
    let id:Int 
} 

extension List { 
    init?(json: [String:AnyObject]) { 
     guard 
      let name = json["name"] as? String, 
      let id = json["id"] as? Int else 
     { 
      return nil 
     } 
     self.name = name 
     self.id = id 
    } 
} 

let listData = json["data"] as? [[String:AnyObject]] 

今まではすべてがうまく見えます。しかし、これが問題の原因です。彼はこのようなものでした :

let list:[List] = listData.flatMap(List.init) 

を上記の行は、リストオブジェクトの配列を返すことになっています。 Chris Edihoffは何の問題もなくこれをやっているようですが、私がそうするとXcodeは警告します

- flatMapは予想される文脈の結果タイプではなく、 '?

ここでもList.initとは何ですか?私はオブジェクトの初期化のこの方法を見たことがありません。 List()である必要があります。ここで顧客の初期化を使用している場合は、List(json:someObject)になるはずです。クリスEdihof話をする

参考:https://www.youtube.com/watch?v=ewk-XNzXzAA

答えて

7

このコードはコンパイルされませんなぜ異なる理由があります。 まず、json["data"]のサブスクリプトを書く必要はありません。フラットマップは、そのデータを繰り返し処理してリストを初期化する仕事です。

元のプレゼンテーションでは、listData.flatMapif letブロックに続くことがわかります。つまり、listDataはアンラップされ、nilではありません。

コードでは、代わりにlet listData = json as? [[String:AnyObject]]があります。あなたのlistDataは、タイプ[[String:AnyObject]]?のオプションです。
だから、この問題を解決する方法は次のとおりです。ここで

if let listData = json as? [[String:AnyObject]] { 
    let list = listData.flatMap(List.init) 
    //do something with list 
} 

、listDataプロパティが正しい型である:[[String: AnyObject]]

List.initについては、flatMapが提供するものに明示的にイニシャライザを明示的に適用する方法です。その機能をもっと冗長に書き直すことはできますが、おそらくより明確な方法です:

listData.flatMap {data in List(json: data)}