RxSwift 연산자 정리 ② - Filtering
Filetering 연산자
Filtering 연산자는 옵저버블
이 방출하는 이벤트를 선택적으로 걸러낼 수 있는 연산자입니다. 이러한 연산자는 특정 조건에 따라 옵저버블
이 방출하는 이벤트를 무시하거나, 걸러내는 데 사용될 수 있습니다. 대표적인 연산자로 take
, skip
, disinctUntilChanged
, filter
, throttle
연산자가 있습니다.
ignoreElements
메서드 | 설명 | 비고 |
---|---|---|
ignoreElements() | 이 연산자는 옵저버블이 이 방출하는 모든 항목을 무시합니다. Completed 와 Error 항목만 방출합니다. | - |
1
2
3
4
Observable<String>.from(["🍏", "🍎", "🍋", "🍓", "🍇"])
.ignoreElements()
.subscribe { print($0) }
.disposed(by: disposeBag)
elementAt
메서드 | 설명 | 비고 |
---|---|---|
element(at:) | 이 연산자는 옵저버블 이 방출하는 항목 중 특정 인덱스에 위치한 항목만 방출합니다. | - |
1
2
3
4
Observable<String>.from(["🍏", "🍎", "🍋", "🍓", "🍇"])
.element(at: 1)
.subscribe { print($0) }
.disposed(by: disposeBag)
filter
메서드 | 설명 | 비고 |
---|---|---|
filter(predicate:) | 이 연산자는 옵저버블 이 방출하는 항목을 필터링합니다. 첫 번째 매개변수로 필터링 조건을 검사한 결과를 Bool 타입으로 반환하는 클로저를 전달해야 합니다. | - |
1
2
3
4
Observable<Int>.from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
.filter { $0 > 3 }
.subscribe { print($0) }
.disposed(by: disposeBag)
skip
메서드 | 설명 | 비고 |
---|---|---|
skip(count:) | 이 연산자는 정해진 숫자만큼 옵저버블 이 방출하는 항목을 생략하고, 이후 항목을 방출합니다. 첫 번째 매개변수로 처음 생략할 항목의 수를 전달해야 합니다. | - |
1
2
3
4
Observable<Int>.from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
.skip(5)
.subscribe { print($0) }
.disposed(by: disposeBag)
skipWhile
메서드 | 설명 | 비고 |
---|---|---|
skip(while:) | 이 연산자는 주어진 조건을 만족하는 동안에만 옵저버블 이 방출하는 항목을 생략하고, 한번이라도 만족하지 않으면 이후 항목을 (검사하지 않고) 모두 방출합니다. 첫 번째 매개변수로 필터링 조건을 검사한 결과를 Bool 타입으로 반환하는 클로저를 전달해야 합니다. | - |
1
2
3
4
Observable<Int>.from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
.skip(while: { $0 % 2 == 1 })
.subscribe { print($0) }
.disposed(by: disposeBag)
skipUntil
메서드 | 설명 | 비고 |
---|---|---|
skip(until:) | 이 연산자는 트리거 옵저버블 이 하나의 항목을 방출할 때까지 소스 옵저버블 이 방출하는 항목을 모두 생략합니다. until 매개변수에 트리거 옵저버블 을 전달해야 합니다. | - |
1
2
3
4
5
6
7
8
9
10
11
12
13
let subject = PublishSubject<Int>()
let trigger = PublishSubject<Void>()
subject
.skip(until: trigger)
.subscribe { print($0) }
.disposed(by: disposeBag)
subject.onNext(10)
trigger.onNext(())
subject.onNext(20)
subject.onNext(30)
subject.onCompleted()
skipDuration
메서드 | 설명 | 비고 |
---|---|---|
skip(duration:scehdular:) | 이 연산자는 지정한 시간 동안 옵저버블 이 방출하는 항목을 생략합니다. 첫 번째 매개변수로 RxTimeInterval 타입을 전달해야 합니다. 일반적으로 .millisecond(Int) , .second(Int) 를 전달합니다. | - |
1
2
3
4
5
Observable<Int>.interval(.seconds(1), scheduler: MainScheduler.instance)
.take(10)
.skip(.seconds(3), scheduler: MainScheduler.instance)
.subscribe { print($0) }
.disposed(by: disposeBag)
take
메서드 | 설명 | 비고 |
---|---|---|
take(count:) | 이 연산자는 정해진 숫자만큼 옵저버블 이 방출하는 항목을 전달하고, 이후 항목을 생략합니다. 첫 번째 매개변수로 전달할 항목의 수를 전달해야 합니다. | - |
1
2
3
4
Observable<Int>.from([1, 2, 3, 4, 5, 6, 7, 8, 9])
.take(5)
.subscribe { print($0) }
.disposed(by: disposeBag)
takeWhile
메서드 | 설명 | 비고 |
---|---|---|
take(while:behavior:) | 이 연산자는 주어진 조건을 만족하는 동안에만 옵저버블 이 방출하는 항목을 전달하고, 한번이라도 만족하지 않으면 이후 항목을 (검사하지 않고) 모두 생략합니다. 첫 번째 매개변수로 필터링 조건을 검사한 결과를 Bool 타입으로 반환하는 클로저를 전달해야 합니다. behavior 매개변수로 TakeBehavior 열거형을 전달해야 합니다. .exclusive 를 전달하면 마지막으로 검사한 항목을 방출하지 않고, .inclusive 를 전달하면 마지막으로 검사한 항목을 방출합니다. | - |
1
2
3
4
5
6
Observable<Int>.from([1, 2, 3, 4, 5, 6, 7, 8, 9])
.take(while: {
!($0 % 4 == 0)
}, behavior: .inclusive)
.subscribe { print($0) }
.disposed(by: disposeBag)
takeUntil
메서드 | 설명 | 비고 |
---|---|---|
take(until:) | 이 연산자는 트리거 옵저버블 이 하나의 항목을 방출할 때까지 소스 옵저버블 이 방출하는 항목을 모두 전달합니다. until 매개변수에 트리거 옵저버블 을 전달해야 합니다. | - |
1
2
3
4
5
6
7
8
9
10
11
12
let subject = PublishSubject<Int>()
let trigger = PublishSubject<Void>()
subject
.take(until: trigger)
.subscribe { print($0) }
.disposed(by: disposeBag)
subject.onNext(10)
subject.onNext(20)
trigger.onNext(())
subject.onNext(30)
takeLast
메서드 | 설명 | 비고 |
---|---|---|
takeLast(count:) | 이 연산자는 정해진 숫자만큼 옵저버블 이 마지막으로 방출한 항목을 버퍼에 저장해두었다가, completed 이벤트를 방출하는 시점에 버퍼에 저장된 항목을 방출합니다. 첫 번째 매개변수로 버퍼에 저장할 항목의 수를 전달해야 합니다. | - |
1
2
3
4
5
6
7
8
9
10
11
12
13
let subject = PublishSubject<Int>()
subject
.takeLast(3)
.subscribe { print($0) }
.disposed(by: disposeBag)
subject.onNext(10)
subject.onNext(20)
subject.onNext(30)
subject.onNext(40)
subject.onNext(50)
subject.onCompleted()
takeFor
메서드 | 설명 | 비고 |
---|---|---|
take(for:scheduler:) | 이 연산자는 지정한 시간 동안 옵저버블 이 방출하는 항목을 전달합니다. 첫 번째 매개변수로 RxTimeInterval 타입을 전달해야 합니다. 일반적으로 .millisecond(Int) , .second(Int) 를 전달합니다. | - |
1
2
3
4
Observable<Int>.interval(.seconds(1), scheduler: MainScheduler.instance)
.take(for: .seconds(5), scheduler: MainScheduler.instance)
.subscribe { print($0) }
.disposed(by: disposeBag)
distinctUntilChanged
메서드 | 설명 | 비고 |
---|---|---|
distinctUntilChanged() | 이 연산자는 옵저버블 이 방출하는 항목과 직전에 방출한 항목이 동일하다면 생략하고, 그렇지 않다면 전달합니다. | - |
distinctUntilChanged(comparer:) | 이 연산자는 옵저버블 이 방출하는 항목과 직전에 방출한 항목이 동일하다면 생략하고, 그렇지 않다면 전달합니다. 첫 번째 매개변수로 옵저버블 이 방출한 항목과 직전에 방출한 항목이 동일한지 검사한 결과를 Bool 타입으로 반환하는 클로저를 전달해야 합니다. | - |
distinctUntilChanged(keySelector:) | 이 연산자는 옵저버블 이 방출하는 항목과 직전에 방출한 항목이 동일하다면 생략하고, 그렇지 않다면 전달합니다. 첫 번째 매개변수로 옵저버블 이 방출한 항목과 직전에 방출한 항목의 (Equatable 프로토콜을 준수하는) 비교 기준을 반환하는 클로저를 전달해야 합니다. | - |
distinctUntilChanged(keyPath:) | 이 연선자는 옵저버블 이 방출하는 항목과 직전에 방출한 항목이 동일하다면 생략하고, 그렇지 않다면 전달합니다. keyPath 매개변수로 키패스(KeyPath)를 전달해야 합니다. | - |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
let numbers = [1, 1, 3, 2, 2, 3, 1, 5, 5, 7, 7, 7]
let tuples = [
(1, "하나"), (1, "둘"), (2, "셋"), (2, "넷")
]
let persons = [
Person(name: "김건우", age: 26),
Person(name: "김문어", age: 15),
Person(name: "김흰둥", age: 5),
Person(name: "김지지", age: 5)
]
Observable<Int>.from(numbers)
.distinctUntilChanged()
.subscribe { print($0) }
.disposed(by: disposeBag)
Observable<(Int, String)>.from(tuples)
.distinctUntilChanged {
return $0.0
}
.subscribe { print($0) }
.disposed(by: disposeBag)
Observable<(Int, String)>.from(tuples)
.distinctUntilChanged {
return $0.0 != $1.0
}
.subscribe { print($0) }
.disposed(by: disposeBag)
Observable<Person>.from(persons)
.distinctUntilChanged(at: \.age)
.subscribe { print($0) }
.disposed(by: disposeBag)
debounce
메서드 | 설명 | 비고 |
---|---|---|
debounce(dueTime:scheduler:) | 이 연산자는 지정한 시간 동안 옵저버블 에서 새로운 항목을 방출하지 않으면, 최근에 방출한 항목을 전달합니다. 첫 번째 매개변수로 RxTimeInterval 타입을 전달해야 합니다. 일반적으로 .millisecond(Int) , .second(Int) 를 전달합니다. | - |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Observable<String>.create { observer in
DispatchQueue.global().async {
for i in 1...10 {
observer.onNext("Next - \(i)")
Thread.sleep(forTimeInterval: 0.3)
}
Thread.sleep(forTimeInterval: 1.0)
for i in 11...20 {
observer.onNext("Next - \(i)")
Thread.sleep(forTimeInterval: 0.5)
}
observer.onCompleted()
}
return Disposables.create()
}
.debounce(.milliseconds(400), scheduler: MainScheduler.instance)
.subscribe { print($0) }
.disposed(by: disposeBag)
throttle
메서드 | 설명 | 비고 |
---|---|---|
throttle(dueTime:latest:scheduler:) | 이 연산자는 지정한 주기 동안 옵저버블 이 최근 방출한 항목을 전달합니다. 첫 번째 매개변수로 RxTimeInterval 타입을 전달해야 합니다. 일반적으로 .millisecond(Int) , .second(Int) 를 전달합니다. latest 매개변수로 Bool 타입을 전달해야 합니다. true 를 전달하면 주기를 정확하게 지키고, false 를 전달하면 주기를 유하게 지킵니다. | - |
1
2
3
4
5
Observable<Int>.interval(.seconds(1), scheduler: MainScheduler.instance)
.take(10)
.throttle(.seconds(2), latest: true, scheduler: MainScheduler.instance)
.subscribe { print($0) }
.disposed(by: disposeBag)
참고 자료
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.