Last active
June 18, 2018 15:20
-
-
Save dennisvennink/bdf3c52ae1d9a3750ec3507ab3262921 to your computer and use it in GitHub Desktop.
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
public struct Zip <Sequence1: Sequence, Sequence2: Sequence> { | |
public struct ShortestSequence: Sequence { | |
internal let sequence1: Sequence1 | |
internal let sequence2: Sequence2 | |
internal init (_ sequence1: Sequence1, _ sequence2: Sequence2) { | |
(self.sequence1, self.sequence2) = (sequence1, sequence2) | |
} | |
public struct Iterator: IteratorProtocol { | |
internal var iterator1: Sequence1.Iterator | |
internal var iterator2: Sequence2.Iterator | |
internal var reachedEnd = false | |
internal init (_ iterator1: Sequence1.Iterator, _ iterator2: Sequence2.Iterator) { | |
(self.iterator1, self.iterator2) = (iterator1, iterator2) | |
} | |
public mutating func next() -> (Sequence1.Iterator.Element, Sequence2.Iterator.Element)? { | |
if self.reachedEnd { | |
return nil | |
} | |
guard let element1 = self.iterator1.next(), let element2 = self.iterator2.next() else { | |
self.reachedEnd.toggle() | |
return nil | |
} | |
return (element1, element2) | |
} | |
} | |
public func makeIterator () -> Iterator { | |
return Iterator(self.sequence1.makeIterator(), self.sequence2.makeIterator()) | |
} | |
} | |
public struct LongestSequence: Sequence { | |
internal let sequence1: Sequence1 | |
internal let sequence2: Sequence2 | |
internal init (_ sequence1: Sequence1, _ sequence2: Sequence2) { | |
(self.sequence1, self.sequence2) = (sequence1, sequence2) | |
} | |
public struct Iterator: IteratorProtocol { | |
internal var iterator1: Sequence1.Iterator | |
internal var iterator2: Sequence2.Iterator | |
internal var reachedEnd = false | |
internal init (_ iterator1: Sequence1.Iterator, _ iterator2: Sequence2.Iterator) { | |
(self.iterator1, self.iterator2) = (iterator1, iterator2) | |
} | |
public mutating func next() -> (Sequence1.Iterator.Element?, Sequence2.Iterator.Element?)? { | |
if self.reachedEnd { | |
return nil | |
} | |
let element1 = self.iterator1.next() | |
let element2 = self.iterator2.next() | |
if element1 == nil && element2 == nil { | |
self.reachedEnd.toggle() | |
return nil | |
} | |
return (element1, element2) | |
} | |
} | |
public func makeIterator () -> Iterator { | |
return Iterator(self.sequence1.makeIterator(), self.sequence2.makeIterator()) | |
} | |
} | |
} | |
public func zip <Sequence1: Sequence, Sequence2: Sequence> (_ sequence1: Sequence1, _ sequence2: Sequence2) -> | |
Zip<Sequence1, Sequence2>.ShortestSequence { | |
return Zip.ShortestSequence(sequence1, sequence2) | |
} | |
public func zipLongest <Sequence1: Sequence, Sequence2: Sequence> (_ sequence1: Sequence1, _ sequence2: Sequence2) -> | |
Zip<Sequence1, Sequence2>.LongestSequence { | |
return Zip.LongestSequence(sequence1, sequence2) | |
} | |
extension Sequence { | |
public func unzip <Type1, Type2> () -> ([Type1], [Type2]) where Self.Element == (Type1, Type2) { | |
return self.reduce(into: ([Type1](), [Type2]())) { (result, element) in | |
result.0.append(element.0) | |
result.1.append(element.1) | |
} | |
} | |
} | |
@available(*, deprecated, renamed: "Zip.ShortestSequence") | |
public typealias Zip2Sequence<Sequence1, Sequence2> = Zip<Sequence1, Sequence2>.ShortestSequence where | |
Sequence1: Sequence, Sequence2: Sequence | |
@available(*, deprecated, renamed: "Zip.ShortestSequence.Iterator") | |
public typealias Zip2Iterator<Sequence1, Sequence2> = Zip<Sequence1, Sequence2>.ShortestSequence.Iterator where | |
Sequence1: Sequence, Sequence2: Sequence |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment