私はこのようなfson json initialiserを持つオブジェクトにいくつかのjsonを直列化しています:
sections = {
let sectionJsons = json["sections"] as! [[String:AnyObject]]
return sectionJsons.map {
DynamicSection($0)
}
}()
DynamicSectionのinit:
init?(_ json:[String:AnyObject]) {
super.init()
//Boring stuff that can fail
私はセクションにinitを渡したDynamicSectionsを追加するだけです。どうすればこれを達成できますか?
私 できる つかいます filter
+map
好きな
return sectionJsons.filter { DynamicSection($0) != nil }.map { DynamicSection($0)! }
しかし、これはDynamicSectionを2回初期化することにつながります。これは避けたいのですが、これを行うにはより良い方法がありますか?
回答:
回答№1の11あなたは使うことができます flatMap
:
return sectionJsons.flatMap { DynamicSection($0) }
例:
struct Foo {
let num: Int
init?(_ num: Int) {
guard num % 2 == 0 else { return nil }
self.num = num
}
}
let arr = Array(1...5) // odd numbers will fail "Foo" initialization
print(arr.flatMap { Foo($0) }) // [Foo(num: 2), Foo(num: 4)]
// or, point to "Foo.init" instead of using an anonymous closure
print(arr.flatMap(Foo.init)) // [Foo(num: 2), Foo(num: 4)]
あなたが連鎖しているのを見るたびに filter
そして map
, flatMap
一般的には良い代替アプローチとして使用できます(フィルタを使用してチェックするときだけでなく nil
エントリ)。
例えば。
// non-init-failable Foo
struct Foo {
let num: Int
init(_ num: Int) {
self.num = num
}
}
let arr = Array(1...5) // we only want to use the even numbers to initialize Foo"s
// chained filter and map
print(arr.filter { $0 % 2 == 0}.map { Foo($0) }) // [Foo(num: 2), Foo(num: 4)]
// or, with flatMap
print(arr.flatMap { $0 % 2 == 0 ? Foo($0) : nil }) // [Foo(num: 2), Foo(num: 4)]