RxSwift基礎-オペレーターその5

RxSwiftで使えるオペレーターを備忘録的に書き綴っていきたいと思います。
また、公式Exanpleを参考にしています。
その1は[こちら](https://qiita.com/masasumi0327/items/ef3d2cf4d014414f42d5)
その2は[こちら](https://qiita.com/masasumi0327/items/c5f2c57420235cb58a5e)
その3は[こちら](https://qiita.com/masasumi0327/items/9bf2ad48f2c6a7183dae)
その4は[こちら](https://qiita.com/masasumi0327/items/fb0f250ab65f6cf5c416)


https://github.com/ReactiveX/RxSwift

また、今回の内容はこちらの動画が非常に解りやすいです。

https://www.youtube.com/watch?v=eP7e8MLz1qI&t=617s


作業環境については、

https://qiita.com/masasumi0327/items/2ae144160987e571bce4

を参考に構築して頂ければと思います。
早速、やっていきましょう!!
## Filtering and Conditional Operators
### filter
```swift
func filter() {
    let disposeBag = DisposeBag()
    
    Observable.of(
        "🐱", "🐰", "🐶",
        "🐸", "🐱", "🐰",
        "🐹", "🐸", "🐱")
        .filter {
            $0 == "🐱" || $0 == "🐶"
        }
        .subscribe(onNext: { print($0) })
        .disposed(by: disposeBag)
}
filter() /*
🐱
🐶
🐱
🐱
*/
```
.filterで🐱か🐶どちらかが**true**なら出力するようにfilteringしています。
シンプルで解りやすいですね。
### distinctUntilChanged
```swift
func distinctUntilChanged() {
    let disposeBag = DisposeBag()
    
    Observable.of("🐱", "🐷", "🐱", "🐱", "🐱", "🐵", "🐱")
        .distinctUntilChanged()
        .subscribe(onNext: { print($0) })
        .disposed(by: disposeBag)
}
distinctUntilChanged() /*
🐱
🐷
🐱
🐵
🐱
*/
```
**distinctUntilChanged**は重複した要素を一つの要素として出力してくれるオペレーターです。
### elementAt
```swift
func elementAt() {
    let disposeBag = DisposeBag()
    
    Observable.of("🐱", "🐰", "🐶", "🐸", "🐷", "🐵")
        .element(at: 3)
        .subscribe(onNext: { print($0) })
        .disposed(by: disposeBag)
}
elementAt() // 🐸
```
element(at:)で指定した数のObservableのみ出力するオペレーターです。
### single
```swift
func single() {
    let disposeBag = DisposeBag()
    
    Observable.of("🐱")
        .single()
        .subscribe(onNext: { print($0) })
        .disposed(by: disposeBag)
}
single() //🐱
```
**single**は流れてくる最初の値、または指定した引数の値のみ流します。
その値が複数ある場合はerrorが流れます。
```swift
func single() {
    let disposeBag = DisposeBag()
    
    Observable.of("🐱", "🐰", "🐶", "🐸", "🐷", "🐵")
        .single { $0 == "🐸" }// 🐸が1つなので正常に流れます
        .subscribe(onNext: { print($0) })
        .disposed(by: disposeBag)
    
    Observable.of("🐱", "🐰", "🐶", "🐱", "🐰", "🐶")
        .single { $0 == "🐰" }// 🐱が2つあるので、2つ目の出力時にerrorが出ます
        .subscribe(onNext: { print($0) })
        .disposed(by: disposeBag)
    
    Observable.of("🐱", "🐰", "🐶", "🐸", "🐷", "🐵")
        .single { $0 == "🔵" }// 🔵が無いので、errorがでます
        .subscribe(onNext: { print($0) })
        .disposed(by: disposeBag)
}
single() /*
🐸
🐰
Unhandled error happened: Sequence contains more than one element.
Unhandled error happened: Sequence doesn't contain any elements.
*/
```
### take
```swift
func take() {
    let disposeBag = DisposeBag()
    
    Observable.of("🐱", "🐰", "🐶", "🐸", "🐷", "🐵")
        .take(3)
        .subscribe(onNext: { print($0) })
        .disposed(by: disposeBag)
}
take() /*
🐱
🐰
🐶
*/
```
**take()**で指定した値まで出力してくれるオペレーターです。
### takeLast
```swift
func takeLast() {
    let disposeBag = DisposeBag()
    
    Observable.of("🐱", "🐰", "🐶", "🐸", "🐷", "🐵")
        .takeLast(3)
        .subscribe(onNext: { print($0) })
        .disposed(by: disposeBag)
}
takeLast() /*
🐸
🐷
🐵
*/
```
**takeLast**はtakeLast()で指定した値が最後から数えたObservableから流してくれるオペレーターです。
### takeWhile
```swift
func takeWhile() {
    let disposeBag = DisposeBag()
    
    Observable.of(1, 2, 3, 4, 5, 6)
        .take(while: { $0 < 4 })
        .subscribe(onNext: { print($0) })
        .disposed(by: disposeBag)
}
takeWhile() /*
1
2
3
*/
```
**takeWhile**はtake(while:)で指定した値がtrueである限り、イベントを流してくれるオペレーターです。
### takeUntil
```swift
func takeUntil() {
    let disposeBag = DisposeBag()
    
    let sourceSequence = PublishSubject<String>()
    let referenceSequence = PublishSubject<String>()
    
    sourceSequence
        .take(until: referenceSequence)
        .subscribe(onNext: { print($0) })
        .disposed(by: disposeBag)
    
    sourceSequence.onNext("🐱")
    sourceSequence.onNext("🐰")
    sourceSequence.onNext("🐶")
    
    referenceSequence.onNext("🔴")// 引数に指定したreferenceSequenceに値が流れたので、これ以降の値が流れない
    
    sourceSequence.onNext("🐸")
    sourceSequence.onNext("🐷")
    sourceSequence.onNext("🐵")
}
takeUntil() /*
🐱
🐰
🐶
*/
```
**takeUntil**はtake(until:)で指定した値が流れるまではイベントを流してくれるオペレーターになります。
### skip
```swift
func skip() {
    let disposeBag = DisposeBag()
    
    Observable.of("🐱", "🐰", "🐶", "🐸", "🐷", "🐵")
        .skip(2)// 最初の値から2つ分飛ばして(スキップして)出力している
        .subscribe(onNext: { print($0) })
        .disposed(by: disposeBag)
}
skip() /*
🐶
🐸
🐷
🐵
*/
```
**skip**はskip()の引数に指定した値分飛ばして、そこからイベントを発行できるオペレーターです。
### skipWhile
```swift
func skipWhile() {
    let disposeBag = DisposeBag()

    Observable.of(1, 2, 3, 4, 5, 6)
        .skip(while: { $0 < 4 })
        .subscribe(onNext: { print($0) })
        .disposed(by: disposeBag)
}
skipWhile() /*
4
5
6
*/
```
**skipWhile**はskip(while:)で指定した値がtrueである限り、指定した値を飛ばしてくれるオペレーターです。
### skipWhileWithIndex
```swift
func skipWhileWithIndex() {
    let disposeBag = DisposeBag()
    
    Observable.of("🐱", "🐰", "🐶", "🐸", "🐷", "🐵")
        .enumerated()// StringのObservableにそれぞれindex番号を付けています
        .skip (while: { $0.index < 3 })
        // .map { $0.element }　　各elementのみの出力に変換している
        .subscribe(onNext: { print($0) })
        .disposed(by: disposeBag)
}
skipWhileWithIndex() /*
(index: 3, element: "🐸")
(index: 4, element: "🐷")
(index: 5, element: "🐵")
*/
```
**skipWhileIndex**は指定したindex番号分飛ばして(スキップして)値を出力しています
### skipUntil
```swift
func skipUntil() {
    let disposeBag = DisposeBag()
    
    let sourceSequence = PublishSubject<String>()
    let referenceSequence = PublishSubject<String>()
    
    sourceSequence
        .skip(until: referenceSequence)
        .subscribe(onNext: { print($0) })
        .disposed(by: disposeBag)
    
    sourceSequence.onNext("🐱")
    sourceSequence.onNext("🐰")
    sourceSequence.onNext("🐶")
    
    referenceSequence.onNext("🔴")
    
    sourceSequence.onNext("🐸")
    sourceSequence.onNext("🐷")
    sourceSequence.onNext("🐵")
}
skipUntil() /*
🐸
🐷
🐵
*/
```
takeUntilの逆転の出力ですね!!
referenceSequenceにイベントが流れるまで出力を飛ばし続けるオペレーターになります。

# 続きは次回に
RxSwiftのオペレーターもこれで半分程学習してきました😀
引き続きオペレーター学習を行い、より良いコードが書ける様に頑張っていきます!!
以上です🥹