take 함수
take 연산자는 take 연산자 괄호 내에 지정된 갯수 만큼의 값을 발행한다.
val observer = Observable.interval(1, TimeUnit.SECONDS)
observer.take(3).subscribe(
~~~
)
위와같이 인자로 3이 들어가있다면 interval로 계속해서 값을 발행하더라도 최초 발행한 3개의 값만 발행시킨다.
map 연산자
map() 함수는 어떠한 입력 값을 함수에 넣어서 원하는 값으로 변환시키는 함수이다. String을 String, Integer, 다른 객체 등으로 변환 할 수 있다.
@CheckReturnValue //반환값을 확인하다는 의미
@SchedulerSupport(value="none") //스케줄러를 지원하지 않는다는 의미로 현재 스레드에서 실행
public final <R> OBservable<R> map(Function<? super T,? extends R> mapper)
위의 BaseCode를 살펴보면 Function 인터페이스를 통해 값이 T로 들어오면 R이라는 결과로 반환 해 주는 것을 알 수 있다.
val numbers = arrayOf(1,2,3,4,5)
Observable.fromArray(*numbers)
.map{ item -> item * 10 }
.subscribe{ print("$it") }
결과 : 10 20 30 40 50 이처럼 기존에 생성되었던 배열이 10씩 곱해진 값으로 변환되어 배출 된 것을 알 수 있다. 조금 더 자세한 예시를 살펴보자면
fun main(args : Array<String>){
val observable = listOf(10,9,8,7,6,5,4,3,2,1).toObservable()
observable.map{ // 숫자 자료형을 가공된 문자열 형태로 변환시키는 map 함수
number -> "Transforming Int to String $number"
}.subscribe{ // 위에서 변형된 형태의 자료들을 print해준다
// 즉 items가 각각의 "Transforming ~~~" 형태의 문자열을 가지게 된다
items -> println("Recived $Item")
}
}
출력결과
Received Transforming Int to String 10
Received Transforming Int to String 9
Received Transforming Int to String 8
Received Transforming Int to String 7
Received Transforming Int to String 6
Received Transforming Int to String 5
Received Transforming Int to String 4
Received Transforming Int to String 3
Received Transforming Int to String 2
Received Transforming Int to String 1
flatmap 연산자
위에서 map이 가공된 향태의 String, Int 형식을 제공 해 주었다면, flatmap 함수는 이러한 자료형들을 Observable 형태로 제공 해 준다. map은 각 배출을 가져와서 변환하지만 flatMap 연산자는 새로운 프로듀서를 만들고 원천 프로듀서에 전달한 함수를 각 배출에 적용한다.
fun main(args : Array<String>){
val observable = listOf(10,9,8,7,6,5,4,3,2,1).toObservable()
observable.flatMap{
number -> Observable.just("Transforming Int to String $number")
}.subscribe{
items -> println("Recived $item")
}
}
이렇게 놓고 봤을 때는 map 연산자와 거의 동일한 출력 결과를 볼 수 있다. 하지만 비슷하긴 해도 적용된 로직에는 차이가 존재한다. 단순히 문자열 형태라 아니라 문자열 형태의 옵저버블을 반환해준다. 이 예제에서는 장점이 잘 보이지 않지만 단일 배출에서 한번에 여러 아이템을 가져와야 하는 경우에는 이야기가 달라진다.
fun main(args : Array<String>){
val observable = listOf(10,9,8,7,6,5,4,3,2,1).toObservable()
observable.flatMap{
number -> Observable.create<String>{
it.onNext("The number $number")
it.onNext("The number/2 ${number/2}")
it.onNext("The number%2 ${number%2}")
it.onComplete()
}
}.subscribeBy{
onNext = {
item -> println("Recieved $item")
},
onComplete = {
println("Complete")
}
}
}
출력결과
Recieved The number 10
Recieved The number/2 5
Recieved The number%2 0
…
…
Recieved The number 1
Recieved The number/2 0
Recieved The number%2 1
Complete
flatmap 연산자 안에 Observable 형태의 또 다른 인스턴스를 생성하고 이 인스턴스는 세 개의 문자열을 반환하게 되어있다. create 연산자로 3개의 문자열을 배출하도록 하고 그 후에 onComplete 알림을 보낸다.
출력을 더 자세히 살펴보면 마지막에 onComplete가 불려오고, 그 전에 모든 항목들을 배출 해 준다는 것을 알 수 있다. flatMap 연산자는 내부적으로 merge 연산자를 사용하기 때문에 먼저 여러 옵저버블들을 결합 후 내보낸다.
repeat 연산자
아이템을 N번 발행한다. 파라미터로 아무 값이 들어가지 않을 시 값을 무한히 발행시킨다.