티스토리 뷰
반응형
FlatMap
FlatMap 함수는 Map 함수를 발전시킨 함수이다. FlatMap 함수는 결과가 Observable로 나옵니다.
Map 함수가 일대일 함수라면 FlatMap 함수는 일대다 혹은 일대일 Observable 함수입니다.
- 빨간색 원을 넣으면 첫 번째 빨간색 다이아몬드, 두 번째 빨간색 다이아몬드가 나온다.
- 초록색 원을 넣으면 같은 방식으로 첫 번째 초록색 다이아몬드, 두 번째 초록색 다이아몬드가 나온다.
위와 같이 FlatMap 함수는 결과 값이 Observable이므로 여러 개의 데이터를 발행할 수 있습니다.
입력
import io.reactivex.Observable
class FlatMapExample {
fun marbleDiagram() {
val getDoubleDiamonds = Function<String, Observable<String>> {
ball -> Observable.just("$ball◇", "$ball◇")
}
val balls = arrayOf("1", "3", "5")
val source = Observable.fromArray(*balls)
.flatMap(getDoubleDiamonds)
source.subscribe { data -> println(data) }
}
}
fun main() {
val demo = FlatMapExample()
demo.marbleDiagram()
}
출력
1◇
1◇
3◇
3◇
5◇
5◇
아래는 람다 표현 식으로 작성한 코드입니다.
입력
import io.reactivex.Observable
class FlatMapExample {fun flatMapLamda() {
val balls = arrayOf("1", "3", "5")
val source = Observable.fromArray(*balls)
.flatMap { ball -> Observable.just("$ball◇", "$ball◇") }
source.subscribe { data -> println(data) }
}
}
fun main() {
val demo = FlatMapExample()
demo.flatMapLamda()
}
출력
1◇
1◇
3◇
3◇
5◇
5◇
구구단 예제
먼저 일반적인 구구단 예제입니다.
입력
import java.util.*
class Gugudan {
fun plainKotlin() {
val scanner = Scanner(System.`in`)
print("Gugudan Input : ")
val dan = scanner.nextInt()
for (row in 1..9) println("$dan * $row = ${dan * row}")
scanner.close()
}
}
fun main() {
val demo = Gugudan()
demo.plainKotlin()
}
아래 코드는 for문을 Observable로 변환한 것입니다.
입력
import io.reactivex.Observable
import java.util.*
class Gugudan {
fun reactiveV1() {
val scanner = Scanner(System.`in`)
print("Gugudan Input : ")
val dan = scanner.nextInt()
val source = Observable.range(1, 9)
source.subscribe { row -> println("$dan * $row = ${dan * row}") }
scanner.close()
}
}
fun main() {
val demo = Gugudan()
demo.reactiveV1()
}
아래 코드는 flatMap 함수를 활용한 것입니다.
입력
import io.reactivex.Observable
import io.reactivex.functions.Function
import java.util.*
class Gugudan {
val scanner = Scanner(System.`in`)
print("Gugudan Input : ")
val dan = scanner.nextInt()
val gugudan = Function<Int, Observable<String>> { num ->
Observable.range(1, 9)
.map { row: Int -> "$num * $row = ${num * row}" }
}
val source = Observable.just(dan).flatMap(gugudan)
source.subscribe { data -> println(data) }
scanner.close()
}
}
fun main() {
val demo = Gugudan()
demo.reactiveV2()
}
아래는 FlatMap 함수 안에 gugudan 함수를 넣은 코드입니다.
입력
import io.reactivex.Observable
import java.util.*
class Gugudan {
fun reactiveV3() {
val scanner = Scanner(System.`in`)
print("Gugudan Input : ")
val dan = scanner.nextInt()
val source = Observable.just(dan)
.flatMap { num -> Observable.range(1, 9) }
.map { row -> println("$dan * $row = ${dan * row}") }
source.subscribe()
scanner.close()
}
}
fun main() {
val demo = Gugudan()
demo.reactiveV3()
}
지금까지 호출한 FlatMap 함수의 원형은 아래와 같습니다.
@SchedulerSupport(SchedulerSupport.NONE)
public final <R> Observable<R> flatMap(Function<? super T, ? extends ObservableSource<? extends R>> mapper) {
return flatMap(mapper, false);
}
SchedulerSupport.NONE은 간단히 현재 스레드에서 실행한다고 보면 됩니다.
ObservableSource은 Observable처럼 데이터를 발행할 수 있는 개체를 포괄해서 지칭합니다.
Single 클래스에는 SingleSource라는 별도 인터페이스가 존재합니다.
아래는 FlatMap 함수의 원형과 조금 다른 형태인 resultSelector를 사용하도록 변경한 FlatMap 코드입니다.
입력
import io.reactivex.Observable
import java.util.*
class Gugudan {
fun usingResultSelector() {
val scanner = Scanner(System.`in`)
print("Gugudan Input : ")
val dan = scanner.nextInt()
val source = Observable.just(dan)
.flatMap({ gugu -> Observable.range(1, 9) }) { gugu, i ->
"$gugu * $i = ${gugu * i}"
}
source.subscribe{ data -> println(data) }
}
}
fun main() {
val demo = Gugudan()
demo.usingResultSelector()
}
반응형
'알려주는 이야기 > RxJava' 카테고리의 다른 글
12. RxJava - Reduce (0) | 2020.07.09 |
---|---|
11. RxJava - Filter (0) | 2020.07.09 |
9. RxJava - Map (0) | 2020.07.09 |
8. RxJava - ConnectableObservable (0) | 2020.07.09 |
7. RxJava - Subject (0) | 2020.07.09 |
댓글