1. flatMap
flatMap() 함수는 map()함수를 좀 더 발전시킨 함수 입니다. map() 함수는 원하는 입력값을 어떤 함수에 넣어서 변환할 수 있는 일대일 함수 입니다. 하지만, flatMap() 함수는 똑같이 함수에 넣더라도 결과가 Observable로 나온다는 것이 다릅니다. 즉 map() 함수가 일대일 함수라면 flatMap() 함수는 일대다(Observable) 함수입니다.
마블다이어그램을 보시면, [빨간색](원) 1개를 입력하면, [빨간색](다이아몬드) 2개가 출력 됩니다. 결과값이 Observable 이므로 여러 개의 데이터를 발행할 수 있습니다. 마블다이어그램을 보시면, 무조건 2개의 데이터를 발행 하는 것 처럼 보이지만 입력 데이터의 속성에 따라서 1개를 발행할 수도 있고, 여러개를 발행할 수도 있습니다. 결과가 Observable이기 때문입니다.
fun flatMapTest1() {
val getDoubleDiamonds = { ball: String ->
Observable.just("${ball}🔶", "${ball}🔶")
}
Observable.fromArray("1", "3", "5")
.flatMap(getDoubleDiamonds)
.subscribe{ str ->
println(str)
}
}
출력 결과
flatMap의 마블다이어그램을 그대로, 위 코드로 작성하였습니다.
2. flatMap을 이용하여 구구단 만들기
fun gugudan() {
Scanner(System.`in`)
.nextInt()
.also { println("$it 단") }
.run {
for (row in 0..9) {
println("$this * $row = ${this * row}")
}
}
}
출력 결과
위와 같은 RxJava를 전혀 사용하지 않은 구구단을 구현한 코틀린 코드가 있습니다. 이것을 RxJava의 flatMap()을 사용해서 구구단을 구현해 보겠습니다.
3. 구구단 구현하기1
fun gugudan1() {
val input = Scanner(System.`in`)
.nextInt()
.also { println("$it 단") }
val gugudan = { input: Int ->
Observable.range(1, 9)
.map { row ->
"$row * $input = ${row * input}"
}
}
Observable.just(input)
.flatMap (gugudan)
.subscribe { println(it) }
}
먼저, Observable.range() 함수를 이용해서 1부터 9까지의 데이터를 만들고, map() 함수를 이용하여, (Int) -> Observable<String>인 함수를 gugudan 이라는 이름으로 구현 하였습니다. 반환값이 Observable<String> 이므로 flatMap의 인자로 사용하여 데이터를 발행할수 있습니다.
4. 구구단 구현하기2
fun gugudan2() {
val input = Scanner(System.`in`)
.nextInt()
.also { println("$it 단") }
Observable.just(input)
.flatMap { input: Int ->
Observable.range(1, 9)
.map { row ->
"$row * $input = ${row * input}"
}
}.subscribe({
println(it)
}, {
println(it.message)
})
}
이번에는, [구구단 구현하기1]에서 gugudan 변수를 inline으로 flatMap의 넣어 구현 하였습니다. 출력값은 [구구단 구현하기1]과 같습니다.
5. 구구단 구현하기3
fun gugudan3() {
val input = Scanner(System.`in`)
.nextInt()
.also { println("$it 단") }
Observable.just(input)
.flatMap (
{ _ -> Observable.range(1, 9)},
{ input, row -> "$input * $row = ${input * row}"}
).subscribe({
println(it)
}, {
println(it.message)
})
}
이번에도 출력 결과는 위와 같습니다. 하지만, 이번에는 flatMap의 인자로(Function, BiFunction)을 가지는 flatMap을 이용하여, 구현 하였습니다.
6. 정리하기
- Observable<R> flatMap(Function<T, R>)
- Observable<R> flatMap(Function<T, U>, BiFunction<T, U, R>)
- flatMap은 Observable을 반환값으로 가집니다.
- RxJava에서 Observable은 여러개의 데이터를 발행한다는 뜻 입니다.
'Reactive Programing' 카테고리의 다른 글
flatMap vs concatMap vs switchMap (2) | 2021.02.03 |
---|---|
Cold Observable vs Hot Observable (PublishSubject 클래스) (0) | 2020.11.22 |
리액티브 프로그래밍 (Reactive Programming) RxJava (0) | 2020.11.01 |
Java API를 RxJava와 통합 하는 방법 (0) | 2020.10.31 |
Flowable 배압(BackPressure) 대응 (0) | 2020.10.30 |