RxSwiftのPlaygroundを読んでみるシリーズ今回は
条件如何で流したり、あるいは流さなかったりする操作についてです。
(Filtering_and_Conditional_Operators)
Filtering and Conditional Operators
様々に条件を設定し、条件に適えばそのまま値を流し、条件に合わなければ値を流しません。
堰のような役割をはたします。
filter
流れてくる値に基づき条件を記述し、条件に合うものだけを流す。
let disposeBag = DisposeBag()
Observable.of(
"🍑", "🍐", "🍎",
"🍇", "🍑", "🍐",
"🍎", "🍇", "🍑"
)
.filter {
$0 == "🍑" // 🍑だけを流す
}
.subscribe { print($0) }
.addDisposableTo(disposeBag)
結果
Next(🍑)
Next(🍑)
Next(🍑)
Completed
distinctUntilChanged
流れてくる値が、前回と違う値だったときのみ流す。
let disposeBag = DisposeBag()
Observable.of(
"🍑", "🍑", "🍑",
"🍎", "🍎", "🍎",
"🍐", "🍐", "🍐"
)
.distinctUntilChanged()
.subscribe { print($0) }
.addDisposableTo(disposeBag)
結果
Next(🍑)
Next(🍎)
Next(🍐)
Completed
elementAt
指定したインデックスの値のみ流す。
let disposeBag = DisposeBag()
Observable.of("🍑", "🍊", "🍇","🍎", "🍏", "🍉")
.elementAt(4)
.subscribe { print($0) }
.addDisposableTo(disposeBag)
結果
Next(🍏)
Completed
single
流れてくる最初の値のみを流す。
あるいは、指定した条件に適う最初の値のみ流す。
条件を指定しない場合に2つ以上の値が流れてきたときや、
条件を指定した場合に、合うものが複数あったとき・合うものがなかったときはerrorが流れる。
条件なし&流れる値が一つ
let disposeBag = DisposeBag()
Observable.just("🍑")
.single()
.subscribe { print($0) }
.addDisposableTo(disposeBag)
Next(🍑)
Completed
条件なし&流れる値が複数
let disposeBag = DisposeBag()
Observable.of("🍑", "🍊", "🍇","🍎", "🍏", "🍉")
.single()
.subscribe { print($0) }
.addDisposableTo(disposeBag)
Next(🍑)
Error(Sequence contains more than one element.)
条件あり&合うものが1つ
let disposeBag = DisposeBag()
Observable.of("🍊", "🍇","🍎", "🍑", "🍏", "🍉")
.single { $0 == "🍑" }
.subscribe { print($0) }
.addDisposableTo(disposeBag)
Next(🍑)
Completed
条件あり&合うものが複数
let disposeBag = DisposeBag()
Observable.of("🍊", "🍑","🍎", "🍑", "🍏", "🍉")
.single { $0 == "🍑" }
.subscribe { print($0) }
.addDisposableTo(disposeBag)
Next(🍑)
Error(Sequence contains more than one element.)
条件あり&合うものがない
let disposeBag = DisposeBag()
Observable.of("🍊", "🍇","🍎", "🍐", "🍏", "🍉")
.single { $0 == "🍑" }
.subscribe { print($0) }
.addDisposableTo(disposeBag)
Error(Sequence doesn't contain any elements.)
take
流れてきた順に指定した数の値を流す。
let disposeBag = DisposeBag()
Observable.of("🍊", "🍇","🍎", "🍑", "🍏", "🍉")
.take(3)
.subscribe { print($0) }
.addDisposableTo(disposeBag)
結果
Next(🍊)
Next(🍇)
Next(🍎)
Completed
takeLast
後ろから数えて指定した数の値を流す。
let disposeBag = DisposeBag()
Observable.of("🍊", "🍇","🍎", "🍑", "🍏", "🍉")
.takeLast(3)
.subscribe { print($0) }
.addDisposableTo(disposeBag)
結果
Next(🍑)
Next(🍏)
Next(🍉)
Completed
takeWhile
条件を満たさなくなるまでは値を流し、それ以降は(条件に合っていても)値を流さない。
let disposeBag = DisposeBag()
Observable.of("🍑", "🍑","🍑", "🍏", "🍑", "🍑")
.takeWhile { $0 == "🍑" }
.subscribe { print($0) }
.addDisposableTo(disposeBag)
結果
Next(🍑)
Next(🍑)
Next(🍑)
Completed
takeUntil
参照する川を指定し、
その川に値が流れるまでは値を流し、
一度参照する川に値が流れると流さなくなる。
let disposeBag = DisposeBag()
let main川 = PublishSubject<String>()
let reference川 = PublishSubject<String>()
main川.takeUntil(reference川)
.subscribe { print($0) }
.addDisposableTo(disposeBag)
main川.onNext("🍑0")
main川.onNext("🍑1")
reference川.onNext("🍏")
main川.onNext("🍑2")
結果
Next(🍑0)
Next(🍑1)
Completed
skip
流れてきた順に指定した数の値をスキップし、それ以降の値を流す。
takeと対照の関係。
let disposeBag = DisposeBag()
Observable.of("🍊", "🍇","🍎", "🍑", "🍏", "🍉")
.skip(3)
.subscribe { print($0) }
.addDisposableTo(disposeBag)
結果
Next(🍑)
Next(🍏)
Next(🍉)
Completed
skipWhile
条件を満たす間は値をスキップし、それ以降は(条件に合っていても)値を流す。
takeWhileと対照の関係。
let disposeBag = DisposeBag()
Observable.of("🍑", "🍑","🍑", "🍏", "🍑", "🍑")
.skipWhile { $0 == "🍑" }
.subscribe { print($0) }
.addDisposableTo(disposeBag)
結果
Next(🍏)
Next(🍑)
Next(🍑)
Completed
skipWhileWithIndex
skipWhileの条件の引数として、インデックスも受け取ることができる。
let disposeBag = DisposeBag()
Observable.of("🍑", "🍑","🍑", "🍏", "🍑", "🍑")
.skipWhileWithIndex { element, index in
index < 4
}
.subscribe { print($0) }
.addDisposableTo(disposeBag)
結果
Next(🍑)
Next(🍑)
Completed
skipUntil
参照する川を指定し、
その川に値が流れるまでは値をスキップし、
一度参照する川に値が流れると値を流すようになる。
takeUntilと対照の関係。
let disposeBag = DisposeBag()
let main川 = PublishSubject<String>()
let reference川 = PublishSubject<String>()
main川.skipUntil(reference川)
.subscribe { print($0) }
.addDisposableTo(disposeBag)
main川.onNext("🍑0")
main川.onNext("🍑1")
reference川.onNext("🍏")
main川.onNext("🍑2")
結果
Next(🍑2)
おわりに
この辺をうまく組み合わせることができれば、
変幻自在な川を作れそうです。
次回は流れる値を集める操作についてです。
参考