Created
February 11, 2015 17:32
-
-
Save almassapargali/068aeccce27b205f527a to your computer and use it in GitHub Desktop.
zipWith for ReactiveCocoa
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// 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