Skip to content

Instantly share code, notes, and snippets.

@kristopherjohnson
Last active July 11, 2018 02:18
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save kristopherjohnson/7419ed4444a0ad9bb2ea to your computer and use it in GitHub Desktop.
Save kristopherjohnson/7419ed4444a0ad9bb2ea to your computer and use it in GitHub Desktop.
zipWith-like function for Swift
/// Given two sequences and a function, return a sequence of results of applying
/// the function to sucessive elements of the sequences.
///
/// Like Haskell's zipWith.
func zipCombine<S1: SequenceType, S2: SequenceType, T>(
sequence1: S1,
_ sequence2: S2,
combine: (S1.Generator.Element, S2.Generator.Element) -> T
) -> AnySequence<T> {
return AnySequence { () -> AnyGenerator<T> in
var gen1 = sequence1.generate()
var gen2 = sequence2.generate()
return anyGenerator {
if let elem1 = gen1.next(), elem2 = gen2.next() {
return combine(elem1, elem2)
}
return nil
}
}
}
// Example
let a1 = [10, 20, 30, 40, 50]
let a2 = [1, 2, 3, 4, 5]
let a = zipCombine(a1, a2, combine: +)
for n in a { print(n) }
// Equivalent to "let zipped = zip(a1, a2)"
let zipped = zipCombine(a1, a2) { ($0, $1) }
for pair in zipped { print("(\(pair.0), \(pair.1))") }
// Is this better? Worse?
func zipCombine2<S1: SequenceType, S2: SequenceType, T>(
sequence1: S1,
_ sequence2: S2,
combine: (S1.Generator.Element, S2.Generator.Element) -> T
) -> AnySequence<T> {
return AnySequence(zip(sequence1.lazy, sequence2.lazy).lazy.map(combine))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment