Skip to content

Instantly share code, notes, and snippets.

@RobertKoval
Created November 10, 2023 16:39
Show Gist options
  • Save RobertKoval/2d91299db5e408e4e51c036a9839f01a to your computer and use it in GitHub Desktop.
Save RobertKoval/2d91299db5e408e4e51c036a9839f01a to your computer and use it in GitHub Desktop.
Combine 2 sequence in order to perform combination mapping (like for inside for)
public struct Combine2Sequence<Base1: Sequence, Base2: Sequence>: Sequence {
private let base1: Base1
private let base2: Base2
public init(_ base1: Base1, _ base2: Base2) {
self.base1 = base1
self.base2 = base2
}
public func makeIterator() -> Iterator {
Iterator(base1Iterator: base1.makeIterator(), base2: base2)
}
public struct Iterator: IteratorProtocol {
private var base1Iterator: Base1.Iterator
private var base2: Base2
private var base2Iterator: Base2.Iterator?
private var currentElement1: Base1.Element?
fileprivate init(base1Iterator: Base1.Iterator, base2: Base2) {
self.base1Iterator = base1Iterator
self.base2 = base2
self.base2Iterator = base2.makeIterator()
self.currentElement1 = self.base1Iterator.next()
}
public mutating func next() -> (Base1.Element, Base2.Element)? {
if let element1 = currentElement1, let element2 = base2Iterator?.next() {
return (element1, element2)
} else if let element1 = base1Iterator.next() {
currentElement1 = element1
self.base2Iterator = base2.makeIterator()
if let element2 = base2Iterator?.next() {
return (element1, element2)
}
}
return nil
}
}
}
func combine<Base1: Sequence, Base2: Sequence>(_ s1: Base1, _ s2: Base2) -> Combine2Sequence<Base1, Base2> {
Combine2Sequence(s1, s2)
}
let combinedSequence = combine([1,2,3], [10,100,1000])
combinedSequence.map(+) == [11,101,1001,12,102,1002,13,103,1003] // true
let combinedSequence1 = combine([2,5,10], [8,10,11])
combinedSequence1.map(*) == [16,20,22,40,50,55,80,100,110] // true
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment