RxKotlinでスリムなRx生活

RxKotlinとは、RxJavaをもっとKotlinらしく使うためのライブラリとのことです。
構成としては、基本的にRxJavaの拡張関数が詰まったものになっています。

##導入
まずは、RxKotlinをプロジェクトに入れます。
最新バージョンは、[0.30.1](http://mvnrepository.com/artifact/io.reactivex/rxkotlin/0.30.1)です。


```build.gradle
dependencies {
	compile 'io.reactivex:rxkotlin:0.30.1'
}
```

##できること

###新しいObservable作成する際に便利な関数

####空のObservableの作成

```observables.kt
public fun <T> emptyObservable() : Observable<T> = Observable.empty()
```

####新しいObservableの作成

```observables.kt
public fun <T> observable(body : (s : Subscriber<in T>) -> Unit) : Observable<T> = Observable.create(body)
```

####リストからのObservableの作成

拡張関数によって、toObservableが追加されており、配列など簡単にObservableにすることができます。

```observables.kt
public fun BooleanArray.toObservable() : Observable<Boolean> = this.toList().toObservable()
public fun ByteArray.toObservable() : Observable<Byte> = this.toList().toObservable()
public fun ShortArray.toObservable() : Observable<Short> = this.toList().toObservable()
public fun IntArray.toObservable() : Observable<Int> = this.toList().toObservable()
public fun LongArray.toObservable() : Observable<Long> = this.toList().toObservable()
public fun FloatArray.toObservable() : Observable<Float> = this.toList().toObservable()
public fun DoubleArray.toObservable() : Observable<Double> = this.toList().toObservable()
public fun <T> Array<out T>.toObservable() : Observable<T> = Observable.from(this)
```

####IteratorからのObservableの作成

```observables.kt
public fun <T> Iterator<T>.toObservable() : Observable<T> = toIterable().toObservable()
public fun <T> Iterable<T>.toObservable() : Observable<T> = Observable.from(this)
public fun <T> Sequence<T>.toObservable() : Observable<T> = Observable.from(object : Iterable<T> {
    override fun iterator(): Iterator<T> = this@toObservable.iterator()
})
```

####単発のObservableの作成

```observables.kt
public fun <T> T.toSingletonObservable() : Observable<T> = Observable.just(this)
public fun <T> Throwable.toObservable() : Observable<T> = Observable.error(this)
```

---

###既存の処理をシンプルに書くための関数

####lift

```observables.kt
public fun <T, R> Observable<T>.lift(operator : (Subscriber<in R>) -> Subscriber<T>) : Observable<R> = lift(object : Observable.Operator<R, T> {
    override fun call(t1: Subscriber<in R>?): Subscriber<in T> = operator(t1!!)
})
```

####combineLatest

```observables.kt
fun <T, R> List<Observable<T>>.combineLatest(combineFunction: (args: List<T>) -> R): Observable<R> =
        Observable.combineLatest(this, { combineFunction(it.asList() as List<T>) })
```

####switchOnNext

```observables.kt
public fun <T> Observable<Observable<T>>.switchOnNext(): Observable<T> = Observable.switchOnNext(this)
```

####zip

```observables.kt
fun <T, R> List<Observable<T>>.zip(zipFunction: (args: List<T>) -> R): Observable<R> =
        Observable.zip(this, { zipFunction(it.asList() as List<T>) })
```

---

###新しく定義された便利な関数

####Nullな値を返さないようにしてくれるfilterNotNull関数

```observables.kt
public fun <T : Any> Observable<T?>.filterNotNull() : Observable<T> = lift { s ->
    subscriber<T?>().
            onCompleted { s.onCompleted() }.
            onError { t -> s.onError(t) }.
            onNext { v -> if (v != null) s.onNext(v) }
}
```

####Nullな値が来た時にエラーを出したい場合はrequireNoNulls関数

```observables.kt
public fun <T : Any> Observable<T?>.requireNoNulls() : Observable<T> = lift { s ->
    subscriber<T?>().
            onCompleted { s.onCompleted() }.
            onError { t -> s.onError(t) }.
            onNext { v -> if (v == null) throw NullPointerException("null element found in rx observable") else s.onNext(v) }
}
```

####値をインデックスの値と共に受け取るにはwithIndex関数

```observables.kt
public fun <T> Observable<T>.withIndex() : Observable<IndexedValue<T>> = lift { s ->
    var index = 0

    subscriber<T>().
            onNext { v -> s.onNext(IndexedValue(index++, v)) }.
            onCompleted { s.onCompleted() }.
            onError { t -> s.onError(t) }
}
```

##おわりに
今回は、ライブラリでobservablesクラス以外は、まだ発展途中な感が強かったでobservables.ktについてだけ触れました！
まだ、バージョンは0.30.1ですが、RxJavaの拡張関数の集まりなので積極的に使っていって問題ない代物ですので、ぜひみなさんも活用してみってはいかがでしょうか。

**RxKotlinのサンプルはまた後日書きたいと思います**