4.8 KiB
Basic Operators
This document explains some of the most common operators used in ReactiveCocoa,
and includes examples demonstrating their use. Note that operators in this context
refer to functions that transform signals, not custom Swift operators. In other
words, these are the composeable primitives provided by ReactiveCocoa for working
with signals. Roughly speaking they take the shape of (Input..., Signal...) -> Signal.
Additionally, this document will use the term "signal" when dealing with concepts that
apply to both Signal and SignalProducer. When the distinction matters the inline
code-style will be used.
Performing side effects with signals
Performing side effects with signals
Observation
Injecting effects
Operator composition
Lifting
Pipe
Transforming signals
These operators transform a signal into a new signal.
Mapping
The map operator is used to transform the values in a signal, creating a new signal with the results.
let (signal, sink) = Signal<String, NoError>.pipe()
let mapped = signal |> map { string in
string.uppercaseString
}
mapped.observe(next: { println($0) })
sendNext(sink, "a") // Prints A
sendNext(sink, "b") // Prints B
sendNext(sink, "c") // Prints C
Filtering
The filter operator is used to include only values in a signal that satisfy a predicate
let (signal, sink) = Signal<Int, NoError>.pipe()
let filtered = signal |> filter { number in
number % 2 == 0
}
filtered.observe(next: { println($0) })
sendNext(sink, 1) // Not printed
sendNext(sink, 2) // Prints 2
sendNext(sink, 3) // Not printed
sendNext(sink, 4) // prints 4
Reducing
The reduce operator is used to aggregate a signals value into a signle combine value. Note, that the final value is only sended after the source signal completes.
let (signal, sink) = Signal<Int, NoError>.pipe()
let filtered = signal |> reduce(1) { $0 * $1 }
filtered.observe(next: { println($0) })
sendNext(sink, 1) // nothing printed
sendNext(sink, 2) // nothing printed
sendNext(sink, 3) // nothing printed
sendCompleted(sink) // prints 6
Combining signals
These operators combine multiple signals into a single new signal.
Combining latest values
The combineLatest function combines the latest values of two (or more) signals. The resulting signal will not send a value until both inputs have sent at least one value each.
let (numbersSignal, numbersSink) = Signal<Int, NoError>.pipe()
let (lettersSignal, lettersSink) = Signal<String, NoError>.pipe()
let combined = combineLatest(numbersSignal, lettersSignal)
combined.observe(next: { println($0) })
sendNext(numbersSink, 0) // nothing printed
sendNext(numbersSink, 1) // nothing printed
sendNext(lettersSink, "A") // prints (1, A)
sendNext(numbersSink, 2) // prints (2, A)
sendNext(lettersSink, "B") // prints (2, B)
sendNext(lettersSink, "C") // prints (2, C)
The combineLatestWith operator works in the same way, but as an operator.
Zipping
The zip function combines values of two signals into pairs. The elements of any Nth pair are the Nth elements of the two input signals.
let (numbersSignal, numbersSink) = Signal<Int, NoError>.pipe()
let (lettersSignal, lettersSink) = Signal<String, NoError>.pipe()
let combined = zip(numbersSignal, lettersSignal)
combined.observe(next: { println($0) })
sendNext(numbersSink, 0) // nothing printed
sendNext(numbersSink, 1) // nothing printed
sendNext(lettersSink, "A") // prints (0, A)
sendNext(numbersSink, 2) // nothing printed
sendNext(lettersSink, "B") // prints (1, B)
sendNext(lettersSink, "C") // prints (2, C)
The zipWith operator works in the same way, but as an operator.