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
*/
이전 값과 같은 중복된 value들을 filtering해준다.
let words = "aabbbaccaddd".publisher
words
.removeDuplicates()
.sink(receiveValue: { print($0) })
.store(in: &cancelBag)
/*prints
a
b
a
c
a
d
*/
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
*/
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
*/
조건을 받는 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
*/
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
*/
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
*/
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
*/
파라미터로 받는 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
*/
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
*/
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
*/
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
*/