Operators Example
Create Operators
Just
just
연산자는 하나의 이벤트를 방출하는 Observable을 생성하는데 이용합니다.
let disposeBag = DisposeBag()
Observable.just("Hello")
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
Observable.just([1, 2, 3, 4, 5], scheduler: MainScheduler.instance)
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
/*
Hello
[1, 2, 3, 4, 5]
*/
위 예시와 같이 just
는 단 하나의 이벤트를 생성하여 방출하고자 할 때 사용합니다.
just
연산자는 두 개의 종류가 제공되며 하나는 방출할 이벤트만 전달하여 생성하고 다른 하나는 방출할 이벤트와 어느 스케줄러로 전송할 지에 대한 스케줄러를 함께 전달하여 생성합니다.
파라미터로 배열을 전달하여도 해당 배열을 통째로 방출하는 것을 확인할 수 있습니다.
Of
앞서 살펴봤던 연산자 just
가 단 하나의 요소를 방출하기 위한 Observable을 생성하는 연산자라면 of
는 가변할 수 있는 개수 만큼의 요소를 방출하기 위한 Observable을 생성하기 위한 연산자입니다.
즉, 방출하고자 하는 이벤트의 개수가 1 ~ N 개인 경우 사용이 가능한 연산자입니다.
let disposeBag = DisposeBag()
let yeo = "Yeo"
let jung = "Jung"
let su = "su"
Observable.of(yeo, jung, su)
.subscribe(onNext: { print($0, terminator: " ") })
.disposed(by: disposeBag)
/*
Yeo Jung Su
*/
From
원형을 살펴보면 함수의 파라미터로 배열을 전달받고 반환형은 배열 요소 타입입니다.
즉 from
연산자는 배열 형태의 element를 전달받아 내부 요소를 순차적으로 방출하는 Observable을 생성합니다.
let disposeBag = DisposeBag()
let arr = ["yeo", "jung", "su"]
Observable.from(arr)
.map { $0 + "😄" }
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
/*
yeo😄
jung😄
su😄
*/
출력 결과를 보면 앞서 얘기했던 것 처럼 배열 내 요소가 순차적으로 방출되어진 것을 볼 수 있습니다.
Filtering Operators
앞서 Observable 생성에 사용되는 주요 연산자들에 대하여 살펴봤습니다.
이번에는 필터링을 위한 연산자들을 살펴보도록 하겠습니다.
filter
필터링 연산자 중 자주 쓰이는 filter
입니다.
요소들을 필터링 하기 위한 기준 predicate
를 클로저로 받아서 해당 결과를 true
값을 반환하는 이벤트를 방출합니다.
let disposeBag = DisposeBag()
let numArr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Observable.from(numArr)
.filter { $0 % 2 == 0 }
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
/*
2
4
6
8
10
*/
filter
파라미터로 전달된 클로저를 살펴보면 element % 2 == 0 즉, 짝수 값만 true를 반환하는 클로저를 전달하였습니다.
따라서, 짝수 element만 출력되어집니다.
take
take
연산자는 정수값을 파라미터로 전달받습니다.
그리고 해당 숫자만큼의 요소만 방출하게 됩니다.
let disposeBag = DisposeBag()
let numArr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Observable.from(numArr)
.take(3)
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
/*
1
2
3
*/
1~10까지의 숫자로 구성된 배열 내 요소를 순차적으로 방출하는 Observable을 생성하고 take
연산자의 파라미터로 3을 전달하였습니다.
그 결과 앞에서부터 3개의 정수만 순차적으로 출력되어진 것을 확인할 수 있습니다.
distinctUntilChanged
다음으로 distinctUntilChanged
연산자입니다.
이름을 보면 느낌이 오듯 요소에 대한 변화가 있을때만 방출하는 연산자입니다.
직접 예시로 살펴보도록 하겠습니다.
let disposeBag = DisposeBag()
let arr = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5]
Observable.from(arr)
.distinctUntilChanged()
.subscribe(onNext: { print ($0) })
.disposed(by: disposeBag)
/*
1
2
3
4
5
*/
arr 배열은 1~5까지 각각의 원소가 순차적으로 두 번씩 반복되는 형태로 제작되었습니다.
해당 배열의 요소들을 순차적으로 방출하는 Observable을 생성한 이후, distinctUntilChanged
함수를 이용하여 필터링을 진행한 결과 방출하고자 하는 요소가 이전 요소와 다른 경우에만 방출되는 것을 확인할 수 있습니다.
Transforming
map
RxSwift의 map의 기능은 Swift에서 사용되는 고차함수 map
과 동일한 기능을 합니다.
다른점이 있다면 Observable을 리턴한다는 것 입니다.
let disposeBag = DisposeBag()
let languageNameArr = ["Swift", "Objective-c", "Kotlin" ,"Go"]
Observable.from(languageNameArr)
.map { "Hello, \($0)" }
.subscribe(onNext: { print($0)})
.disposed(by: disposeBag
/*
Hello, Swift
Hello, Objective-c
Hello, Kotlin
Hello, Go
*/
Combining
concat
concat
타입메서드는 sequence
타입, collection
타입 등을 파라미터로 전달받아 해당 컬렉션 내부에 있는 요소들을 순차적으로 연결하여 하나의 Observable로 반환합니다.
let disposeBag = DisposeBag()
let oneToFive = Observable.from([1, 2, 3, 4, 5])
let sixToTen = Observable.from([6, 7, 8, 9, 10])
Observable.concat([oneToFive, sixToTen])
.subscribe(onNext: { print ($0)} )
.disposed(by: disposeBag)
/*
1
2
3
4
5
6
7
8
9
10
*/
CombineLatest
combineLatest
연산자는 여러 형태의 메소드를 제공하지만 가장 기본적으로 사용되는 형태는 위와 같습니다.
두 개의 Observable O1, O2를 전달받고 resultSelector라는 클로저를 전달받습니다.
해당 클로저 내부에는 O1, O2의 element가 전달되고, 클로저의 실행 결과는 element 하나의 요소를 리턴합니다.
이어서 최종적으로 클로저가 리터너한 하나의 요소를 방출하는 Observable을 반환합니다.
combineLatest는 최대 8개 까지 Observable을 전달받을 수 있도록 선언되어 있으며 파라미터의 개수만 다를뿐 동작은 동일합니다.
let disposeBag = DisposeBag()
let platforms = PublishSubject<String>()
let languages = PublishSubject<String>()
Observable.combineLatest(platforms, languages) { " Hi \($0 + " " + $1)"}
.subscribe(onNext: { print ($0) })
.disposed(by: disposeBag)
platforms.onNext("iOS")
languages.onNext("Swift")
platforms.onNext("AOS")
languages.onNext("Kotlin")
/*
Hi iOS Swift
Hi AOS Swift
Hi AOS Kotlin
*/
두 개의 Observable에서 최근에 방출된, Latest한 요소값들 끼리의 조합 결과를 반환하기에 위와 같은 결과를 볼 수 있습니다.
zip
zip
연산자는 source Observable이 방출하는 요소들을 결합합니다.
앞서 살펴봤던 combineLatest
연산자는 가장 최근 요소들을 기준으로 클로저를 실행하지만 zip
은 클로저에게 중복되는 요소를 전달하지 않습니다.
index 기준으로 짝을 맞춰 요소를 전달하여 작동하게 됩니다.
let disposeBag = DisposeBag()
let numbers = PublishSubject<Int>()
let strings = PublishSubject<String>()
Observable.zip(numbers, strings) { "\($0)" + " " + "\($1)" }
.subscribe(onNext: { print ($0) })
.disposed(by: disposeBag)
numbers.onNext(1)
strings.onNext("One")
numbers.onNext(2)
strings.onNext("Two")
numbers.onNext(3)
strings.onNext("Three")
/*
1 One
2 Two
3 Three
*/
Summary
Create
-
just
: 단 하나의 이벤트를 방출하는 Observable 생성 -
of
: 하나 혹은 여러 개의 이벤트를 방출하는 Observable 생성 -
from
: 배열 형태의 element를 전달받아 내부 요소를 하나하나 방출하는 Observable을 생성
Filter
-
filter
: 함수 파라미터로 predicate 역할의 클로저를 전달받으며 해당 결과가 true 값인 요소만 방출됩니다. -
take
: 함수 파라미터로 정수값을 전달받으며 해당 숫자만큼의 이벤트를 방출합니다. -
distinctUntilChanged
: 이전에 방출한 요소값과 현재의 요소가 다른 경우에만 요소를 방출합니다.
Transforming
map
: Swift의 고차함수 map과 동일한 기능을 하며 Observable을 반환합니다.
Combining
-
concat
: 이름 그대로 컬렉션 타입의 파라미터들을 순차적으로 연결하여 하나의 Observable을 반환합니다. -
combineLatest
: 하나 이상의 Observable을 파라미터로 전달받으며 해당 Observable의 요소들 중 최근값들을 조합한 값을 반환하는 Observable을 반환합니다. -
zip
: 1~3개 의 source Observable을 파라미터로 전달받으며 해당 Observable의 요소들을 index 순에 맞춰서 조합한 값을 반환하는 Observable을 반환합니다.
'iOS' 카테고리의 다른 글
[iOS] [Swift] UIKit Framework (0) | 2020.12.04 |
---|---|
[iOS] [Swift] RxCocoa 맛보기 (0) | 2020.11.26 |
[iOS] [Swift] RxSwift Subject & Relay & Driver (1) | 2020.11.19 |
[iOS] [Swift] RxSwift Observable & Observer, Disposable (0) | 2020.11.19 |
[iOS] Blur Effect in iOS (0) | 2020.11.11 |