RxSwift Transforming Operators   

##Transforming Operatorsまとめ  

RxSwiftでコードを書く必要があり、学習中です。
参考文献を元に学んだ内容をすぐ振り返れるようにまとめていきます。
今回はTransforming Operatorsについてまとめました。
完全に自分の解釈でコメントを載せていますが、解釈に誤りがありましたら、コメント欄より教えてください。

### toArray()
Observableから発火されたelementをArrayに詰め込んでSingleで返す。

```Swift
import Foundation
import RxSwift

    let disposeBag = DisposeBag()
    // 1
    Observable.of("A", "B", "C")
        // 2
        .toArray()
        .subscribe(onSuccess: {
            print($0)
        })
        .disposed(by: disposeBag)

```

**コンパイル結果**
![Screen Shot 2020-11-24 at 3.16.47 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535198/03ce2b1b-0bb3-a350-efc9-7b53763049e1.png)

###map()
標準と一緒。各値に処理を加えて返す。ただし、nilが含まれる可能性がある場合はOptionalを返す。

```Swift
    let disposeBag = DisposeBag()
    
    // 1
    let formatter = NumberFormatter()
    formatter.numberStyle = .spellOut
    
    // 2
    Observable<Int>.of(123, 4, 56)
        // 3
        .map {
            formatter.string(for: $0) ?? ""
        }
        .subscribe(onNext: {
            print($0)
        })
        .disposed(by: disposeBag)
```
**コンパイル結果**
![Screen Shot 2020-11-24 at 3.18.30 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535198/2b9b6150-1a7d-0159-526a-90a79aac5b94.png)



###enimerated()
Observableから受け取った値にindexを振り管理できる。

```Swift
    let disposeBag = DisposeBag()
    
    // 1
    Observable.of(1, 2, 3, 4, 5, 6)
        // 2
        .enumerated()
        // 3
        .map { index, integer in
            index > 2 ? integer * 2 : integer
        }
        // 4
        .subscribe(onNext: {
            print($0)
        })
        .disposed(by: disposeBag)
```
**コンパイル結果**
![Screen Shot 2020-11-24 at 3.20.46 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535198/5b4050b6-03f8-bc03-9e28-221e23b5d7f7.png)


###compactMap()
map+nilを取り除くfilter: オプショナルをアンラップして、nilがある場合、nilを破棄。


```Swift
    let disposeBag = DisposeBag()
    
    // 1
    Observable.of("To", "be", nil, "or", "not", "to", "be", nil)
        // 2
        .compactMap { $0 }
        // 3
        .toArray()
        // 4
        .map { $0.joined(separator: " ") }
        // 5
        .subscribe(onSuccess: {
            print($0)
        })
        .disposed(by: disposeBag)

```
**コンパイル結果**
![Screen Shot 2020-11-24 at 3.22.18 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535198/d4605cab-d484-2f43-61ac-d4d08d75e0f4.png)



###flatMap()
後述のflatMap()と異なり、Observableが変わっても、継続して以前のObservableから値を受け取り続ける。
map()だと返り値は以下の  となる。
RxSwift.BehaviorSubject<Swift.Int>

flatMap()することで、Array(s.map(transform).joined()).と同等の処理がされるため、
Array <Array < Element>>をArray<Element>にすることができる。


```Swift

struct Student {
    let score: BehaviorSubject<Int>
}

    let disposeBag = DisposeBag()
    
    // 1
    let laura = Student(score: BehaviorSubject(value: 80))
    let charlotte = Student(score: BehaviorSubject(value: 90))
    
    // 2
    let student = PublishSubject<Student>()
    
    // 3
    student
        .flatMap {
            $0.score
        }
        // 4
        .subscribe(onNext: {
            print($0)
        })
        .disposed(by: disposeBag)
    
    student.onNext(laura)
    laura.score.onNext(85)
    student.onNext(charlotte)
    laura.score.onNext(95)
    charlotte.score.onNext(100)

```

**コンパイル結果**
![Screen Shot 2020-11-24 at 3.22.40 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535198/604528c3-2f61-ee66-f9a2-a24b50554c9d.png)


###flatMapLatest()
Map +  switchLatest: Observableが変わったら最新のObservableからのみ値を受け取り、前のObservableからは値を受け取らない。

```Swift
    let disposeBag = DisposeBag()
    
    let laura = Student(score: BehaviorSubject(value: 80))
    let charlotte = Student(score: BehaviorSubject(value: 90))
    
    let student = PublishSubject<Student>()
    
    student
        .flatMapLatest {
            $0.score
        }
        .subscribe(onNext: {
            print($0)
        })
        .disposed(by: disposeBag)
    
    student.onNext(laura)
    laura.score.onNext(85)
    student.onNext(charlotte)
    
    // 1
    laura.score.onNext(95)
    charlotte.score.onNext(100)
````
**コンパイル結果**
![Screen Shot 2020-11-24 at 3.22.55 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535198/c31edaca-7a4e-0ab2-118d-59d2143055af.png)


###materialize() && dematerialize()
materialize()しない場合、エラーが起こったとき、そこでdisposeされてしまうが、materialize()することでelementをeventに変換し、.dematerialize()でelementに戻すことで、エラーが起こったObservableはUnsubscribeされるが、別のObservableは継続して使用することができる。

```Swift
    // 1
    enum MyError: Error {
        case anError
    }
    
    let disposeBag = DisposeBag()
    
    // 2
    let laura = Student(score: BehaviorSubject(value: 80))
    let charlotte = Student(score: BehaviorSubject(value: 100))
    
    let student = BehaviorSubject(value: laura)
    
    // 1
    let studentScore = student
        .flatMapLatest {
            $0.score.materialize()
        }
    
    // 2
    studentScore
        // 1
        .filter {
            guard $0.error == nil else {
                print($0.error!)
                return false
            }
            
            return true
        }
        // 2
        .dematerialize()
        .subscribe(onNext: {
            print($0)
        })
        .disposed(by: disposeBag)
    
    
    // 3
    laura.score.onNext(85)
    
    laura.score.onError(MyError.anError)
    
    laura.score.onNext(90)
    
    // 4
    student.onNext(charlotte)

```

**コンパイル結果**
![Screen Shot 2020-11-24 at 3.23.10 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535198/7651edab-ea87-37da-deb6-3e52057eb243.png)

##参考文献
1.RxSwift: Reactive Programming with Swift
Chapter7 Transforming Operators Written by Scott Gardner
詳細が気になる方はこちらをご参照ください！
https://www.raywenderlich.com/13285844-rxswift-reactive-programming-with-swift-update-now-available

2.https://www.swiftbysundell.com/basics/map-flatmap-and-compactmap/

3.https://www.avanderlee.com/swift/compactmap-flatmap-differences-explained/

4.https://academy.realm.io/jp/posts/try-swift-soroush-khanlou-sequence-collection/