zukkeyの技術奮闘記

”当たり前”が誰かのためになる、はず

RxKotlin:{distinct, distinctUntilChanged, ElementAt, buffer, takeUntil, throttleFirst}編

はじめに

前回、5つのオペレータについてご紹介したのでその続きです。

rozkey.hatenablog.com

 

Distinct

distinctメソッドは一度通知したデータと同じデータを通知しないようにするオペレータです。

サンプルプログラムを作成したので見ていきましょう。

fun main(args: Array<String>) {
val array: Array<String> = arrayOf("allow", "bow", "bow", "dead", "allow", "bow", "bow", "dead")
Observable.from(array)
.distinct()
.subscribe({
println(it)
}, {})
}

重複した文字列を含むObservableを作成してdistinctメソッドで重複した値を取り除いて出力するようにしています。

実行結果は以下になります。

f:id:rozkey59:20180212153856p:plain

allow, bow, deadが重複していたので一度表示された後は一切表示されていないことが分かります。

大文字小文字に関係なく重複したデータを取り除くこともできます。

 

DistinctUntilChanged

DistinctUntilChangedはDistinctに似ているのですが、連続して重複したデータを通知しません。”連続して”というところが肝です。

サンプルを見ていきましょう。

fun main(args: Array<String>) {
val array: Array<String> = arrayOf("allow", "bow", "bow", "dead", "allow", "bow", "bow", "dead")
Observable.from(array)
.distinctUntilChanged()
.subscribe({
println(it)
}, {})
}

先ほどと同じ文字列を持つObservableを用意してdistinctUntilChangedメソッドを呼ぶようにしました。

 

実行結果が以下になります。

f:id:rozkey59:20180210235404p:plain

先ほどとは違っているのが連続していないので2回目のallow, bow, deadが表示されています。

 

ElementAt

elementAtメソッドでは指定したインデックスのデータのみを通知します。

サンプルプログラムを見ていきましょう。

fun main(args: Array<String>) {
val array: Array<String> = arrayOf("allow", "bow", "community", "dead")
Observable.from(array)
.elementAt(2)
.subscribe({
println(it)
}, {})
}

文字列のObservableを生成して配列のインデックス2を指定しています。

一応ですが、{0: allow, 1: bow, 2: community, 3: dead}です。

実行した結果が以下になります。

 

f:id:rozkey59:20180210235856p:plain

指定した配列のインデックス2のcommunityだけが表示されているのが確認できます。

 

Buffer

bufferメソッドは通知するデータを指定した範囲でまとめてListなどにして通知することができます。

 

サンプルプログラムを見ていきましょう。

fun main(args: Array<String>) {
val array: Array<String> = arrayOf("allow", "bow", "community", "dead", "easy", "face", "guard", "hint")
Observable.from(array)
.buffer(3)
.subscribe({
println(it)
}, {})
}

いつも通りに文字列のObservableを生成してbufferメソッドで3件ごとにまとめて通知するようにしてあります。

 

この実行結果を見てみましょう。

f:id:rozkey59:20180211000328p:plain

確かに3件ごとのListになって通知されているのが分かります。

 

TakeUntil

takeUntilメソッドは、指定した条件になるまでデータを通知することができるメソッドです。前回のtakeの+αみたいなやつです。

サンプルプログラムを見ていきましょう。

fun main(args: Array<String>) {
val array: Array<String> = arrayOf("allow", "bow", "", "dead", "easy", "face", "guard", "hint")
Observable.from(array)
.takeUntil{ data -> data == "face" }
.subscribe({
println(it)
}, {})
}

いつも通りに文字列のObservableを生成してfaceが来るまで通知するようにしています。

実行結果は以下になります。

f:id:rozkey59:20180211000801p:plain

確かに期待した結果通りになっているのが確認できます。

 

throttleFirst

throttleFirstメソッドでは、データを通知後の指定した期間では他のデータを通さないということができます。指定した期間に通知されるデータを破棄し繰り返します。

 

サンプルプログラムを見ていきましょう。

fun main(args: Array<String>) {
Observable.interval(500L, TimeUnit.MILLISECONDS)
.throttleFirst(1000L, TimeUnit.MILLISECONDS)
.subscribe({
val time = LocalTime.now()
println("time: " + time + ", data: " + it.toString())
}, {})
Thread.sleep(10000L)
}

intervalメソッドは指定した期間の間隔で数値を通知することができるオペレータです。

今回は0.5秒ごとに0、1、2とLong値の数字を通知するObservableを生成して、1秒間は通知させないようにしています。

 

実行結果を見ていきましょう。

f:id:rozkey59:20180211004324g:plain

確かに指定した時間でほかのデータを通知出来ないようにしているのが確認できます。

 

まとめ

今回は前回に引き続きRxKotlinでdistinct, distinctUntilChanged, ElementAt, buffer, takeUntil, throttleFirstのオペレーターの紹介を行いました。

間違っていることとかあればコメントしていただけると嬉しいです!

次回は合成オペレーターについて紹介します。