Combine) Filtering Operators

Havi·2022년 3월 5일
1

Combine

목록 보기
6/8

filter()

filter operator는 bool을 반환하는 closure를 제공한다. closure의 결과가 true일 때만 value를 emit한다.

let numbers = (1...10).publisher
numbers
    .filter { $0.isMultiple(of: 3) }
    .sink(receiveValue: { print($0) })
    .store(in: &cancelBag)
/* prints
3
6
9
*/

removeDuplicates()

이전 값과 같은 중복된 value들을 filtering해준다.

let words = "aabbbaccaddd".publisher
words
    .removeDuplicates()
    .sink(receiveValue: { print($0) })
    .store(in: &cancelBag)
/*prints
a
b
a
c
a
d
*/

compactMap()

map과 같은 개념인데 nil인 값을 무시한다.

let stringArray = ["0", "a", "3", "car", "421"].publisher
stringArray
    .compactMap(Int.init)
    .sink(receiveValue: { print($0) })
    .store(in: &cancelBag)
/*prints
0
3
421
*/

ignoreOutput()

emitting 되는 values를 모두 무시한다.
publisher가 emitting values를 끝냈는지만 알고싶을 때 사용한다.

let numbers = (1...10_000).publisher
numbers
    .ignoreOutput()
    .sink(receiveCompletion: { print("Completed with: \($0)") },
          receiveValue: { print($0) })
    .store(in: &cancelBag)
/*prints
Completed with: finished
*/

first(where:)

조건을 받는 closure를 받는다. 해당 조건에 맞는 첫번 째 값을 방출하고 complete한다.

let numbers = (1...9).publisher
numbers
    .first(where: { $0 % 2 == 0 })
    .sink(receiveCompletion: { print("Completed with: \($0)") },
          receiveValue: { print($0) })
    .store(in: &cancelBag)
/*prints
2
Completed with: finished
*/

last(where:)

first와 반대로 upstream이 complete된 뒤에 조건에 맞는 마지막 value를 emit한다.

let numbers = (1...9).publisher
numbers
    .last(where: { $0 % 2 == 0 })
    .sink(receiveCompletion: { print("Completed with: \($0)") },
          receiveValue: { print($0) })
    .store(in: &cancelBag)
/*prints
8
Completed with: finished
*/

dropFirst()

RxSwift의 skip과 같이 count개의 values의 emit를 무시하는 operator

let numbers = (1...9).publisher
numbers
    .dropFirst(3)
    .sink(receiveCompletion: { print("Completed with: \($0)") },
          receiveValue: { print($0) })
    .store(in: &cancelBag)
/*prints 
4
5
6
7
8
9
Completed with: finished
*/

drop(while:)

while 안에 처음 predicate closure가 만족할 때까지 drop한다.

let numbers = (1...9).publisher
numbers
    .drop(while: { $0 / 2 != 2 }) // 4가 만족하므로 4부터 emit
    .sink(receiveCompletion: { print("Completed with: \($0)") },
          receiveValue: { print($0) })
    .store(in: &cancelBag)
/*prints
4
5
6
7
8
9
Completed with: finished
*/

drop(untilOutputFrom:)

파라미터로 받는 publisher에서 value를 emit하기 전에 방출된 값들을 모두 drop한다.

let isReady: PassthroughSubject<Void, Never> = .init()
let taps: PassthroughSubject<Int, Never> = .init()

taps
    .drop(untilOutputFrom: isReady)
    .sink(receiveValue: { print($0) })
    .store(in: &cancelBag)

taps.send(1)
taps.send(2)
taps.send(3)
isReady.send(())
taps.send(4)
taps.send(5)
isReady.send(completion: .finished)
taps.send(completion: .finished)
/*prints
4
5
*/

prefix()

count만큼의 방출된 값만 받고 complete된다.

let numbers = (1...9).publisher
numbers
    .prefix(3)
    .sink(receiveCompletion: { print("Completed with: \($0)") },
          receiveValue: { print($0) })
    .store(in: &cancelBag)
/*prints
1
2
3
*/

prefix(while:)

while closure 안의 조건이 만족할 때까지만 값을 받고 complete된다.

let numbers = (1...9).publisher
numbers
    .prefix(while: { $0 < 4 })
    .sink(receiveCompletion: { print("Completed with: \($0)") },
          receiveValue: { print($0) })
    .store(in: &cancelBag)
/*prints
1
2
3
Completed with: finished
*/

prefix(untilOutputFrom:)

parameter안의 publisher이 값을 방출할 때까지만 값을 받고 complete된다.

let isReady: PassthroughSubject<Void, Never> = .init()
let taps: PassthroughSubject<Int, Never> = .init()

taps
    .prefix(untilOutputFrom: isReady)
    .sink(receiveValue: { print($0) })
    .store(in: &cancelBag)

taps.send(1)
taps.send(2)
taps.send(3)
isReady.send(())
taps.send(4)
taps.send(5)
isReady.send(completion: .finished)
taps.send(completion: .finished)

/*prints
1
2
3
*/
profile
iOS Developer

0개의 댓글