LoginSignup
4
4

More than 5 years have passed since last update.

Swift2のArray.flatmapっぽい使い方ができるRxSwift拡張の提案

Posted at

ご存知のとおり、Swift2からのArray.flatmap()は、Optionalを返す関数を渡すとArrayに戻してくれて、かつnilを捨ててくれるという便利機能が実装されています。

参考: Swift 2.0の新しいflatMapが便利過ぎる
http://qiita.com/koher/items/6a95cb8edb04fb81f787

RxSwiftのObservableにも同じ使い勝手で使えるflatmapを実装することができます。
便利そうな気もしますが、わかりにくいかもしれません。


extension Observable {
    /**
    example:
    Observable<String>.of("1", "a", "3", "4")
            .flatMap { Int($0) }
            .subscribeNext { print("\($0)") }
    result:
    1
    3
    4
    */
    func flatMap<T>(selector: (E) throws -> T?) -> Observable<T> {
        return flatMap { try selector($0).map { Observable<T>.just($0) } ?? Observable<T>.empty() }
    }
}

extension Driver {
    /**
    example:
    Driver<String>.of("1", "a", "3", "4")
            .flatMap { Int($0) }
            .driveNext { print("\($0)") }
    result:
    1
    3
    4
    */
    func flatMap<T>(selector: (E) -> T?) -> Driver<T> {
        return flatMap { selector($0).map { Driver<T>.just($0) } ?? Driver<T>.empty() }
    }
}

たとえばこんな処理が、、、

Observable<String>.of("1", "a", "3", "4", "5", "c", "d", "8")
    .map { (v : String) -> Int? in return Int(v) }      // <- Int(String)が 失敗したときnilを返す
    .filter { (v : Int?) -> Bool in return (v != nil) } // <- 失敗した結果を捨てる
    .map { (v : Int?) -> Int in return v! }             // <- Optionalをunwrap
    .subscribeNext { print("\($0)") }

または、RxSwiftExt ( https://github.com/RxSwiftCommunity/RxSwiftExt ) をお使いの場合はこんな感じになると思いますが、、

Observable<String>.of("1", "a", "3", "4", "5", "c", "d", "8")
    .map { (v : String) -> Int? in return Int(v) }
    .unwrap ()
    .subscribeNext { print("\($0)") }

こんな感じで書けるようになります

Observable<String>.of("1", "a", "3", "4", "5", "c", "d", "8")
    .flatMap { (v : String) -> Int? in return Int(v) }
    .subscribeNext { print("\($0)") }

しかしやはり、便利そうな気もしますが、わかりにくいかもしれません。

gistはこちら
https://gist.github.com/gamako/01a3646103f065473ade766f9ad21287

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4