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