Skip to content

Instantly share code, notes, and snippets.

@almassapargali
Created February 11, 2015 17:32
Show Gist options
  • Save almassapargali/068aeccce27b205f527a to your computer and use it in GitHub Desktop.
Save almassapargali/068aeccce27b205f527a to your computer and use it in GitHub Desktop.
zipWith for ReactiveCocoa
/// Zips elements of two signals into pairs. The elements of any Nth pair
/// are the Nth elements of the two input signals.
public func zipWith<T, U, E>(otherSignal: Signal<U, E>)(signal: Signal<T, E>) -> Signal<(T, U), E> {
return Signal { observer in
let lock = NSRecursiveLock()
lock.name = "org.reactivecocoa.ReactiveCocoa.zipWith"
var signalValues: [T] = []
var otherValues: [U] = []
enum Either<T, U> {
case Left(T)
case Right(U)
}
let appendAndFlushValues: Either<T, U> -> () = { either in
var tuple: (T, U)?
lock.lock()
switch either {
case let .Left(val):
signalValues.append(val)
case let .Right(val):
otherValues.append(val)
}
if !signalValues.isEmpty && !otherValues.isEmpty {
tuple = (signalValues.removeAtIndex(0), otherValues.removeAtIndex(0))
}
lock.unlock()
if let tuple = tuple {
sendNext(observer, tuple)
}
}
let onError = { sendError(observer, $0) }
let onCompleted = { sendCompleted(observer) }
let signalDisposable = signal.observe(next: { value in
appendAndFlushValues(.Left(value))
}, error: onError, completed: onCompleted)
let otherDisposable = otherSignal.observe(next: { value in
appendAndFlushValues(.Right(value))
}, error: onError, completed: onCompleted)
return CompositeDisposable([ signalDisposable, otherDisposable ])
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment