emahiro/b.log

日々の勉強の記録とか育児の記録とか。

Computed Property で for を使った構文を map を使った構文へ書き換える

computed property内でforを使った実装をしていた部分をmapを使ったswiftらしい構文へ書き換えました。

変更対象コード

var isSuccess: Bool {       
    for q in questions {
        if !q.isSuccess {
            return false
        }
    }
    return true
}

変換第一段階は以下

var isSuccess: Bool {   
    questions.map { q in
        if !q.isSuccess {
            return false
        }
        return true
    }
}

このままだと Ambiguous reference to member mapxcodeに怒られる

var isSuccess: Bool {
    questions.map { q -> Bool in
        if !q.isSuccess {
            return false
        }
        return true
    }
}

参考: http://stackoverflow.com/questions/34368958/ambiguous-reference-to-member-map-when-attempting-to-append-replace-array-elem

mapはクロージャーの中で返り値の方を指定する必要がある。 しかしこれでも返り値はBoolなので、返り値の型が違うのでおこらえる。 mapでの返り値はCollection型で返ってくるので、返り値はBool指定しないと行けない。

そこでやりたかった意図は questionsの回答状況が全てSuccessであればisSuccessがtrue ということなので、mapで返されたCollectionの中身が全てtrueである、つまりfalseを含まなければいいというロジックになる。

var isSuccess: Bool {
    let status = questions.map { q -> Bool in
        if !q.isSuccess {
            return false
        }
        return true
    }
    return !status.contains(false)
}