Created
June 19, 2018 17:31
-
-
Save dennisvennink/7699612547a4d6aae8e2d1b136fceaf2 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 Pair <Type1, Type2> { | |
public let first: Type1 | |
public let second: Type2 | |
public init (_ first: Type1, _ second: Type2) { | |
(self.first, self.second) = (first, second) | |
} | |
} | |
extension Pair { | |
func fill <WrappedType1, WrappedType2> (_ first: WrappedType1, _ second: WrappedType2) -> Pair<WrappedType1, WrappedType2> where Type1 == Optional<WrappedType1>, Type2 == Optional<WrappedType2> { | |
return Pair<WrappedType1, WrappedType2>(self.first ?? first, self.second ?? second) | |
} | |
} | |
extension Pair where Type1: Sequence, Type2: Sequence { | |
public enum Zip { | |
public struct LongestSequence: Sequence { | |
internal let sequence1: Type1 | |
internal let sequence2: Type2 | |
internal init (_ sequence1: Type1, _ sequence2: Type2) { | |
(self.sequence1, self.sequence2) = (sequence1, sequence2) | |
} | |
public struct Iterator: IteratorProtocol { | |
internal var iterator1: Type1.Iterator | |
internal var iterator2: Type2.Iterator | |
internal var reachedEnd = false | |
internal init (_ iterator1: Type1.Iterator, _ iterator2: Type2.Iterator) { | |
(self.iterator1, self.iterator2) = (iterator1, iterator2) | |
} | |
public mutating func next() -> (Type1.Iterator.Element?, Type2.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 struct ShortestSequence: Sequence { | |
internal let sequence1: Type1 | |
internal let sequence2: Type2 | |
internal init (_ sequence1: Type1, _ sequence2: Type2) { | |
(self.sequence1, self.sequence2) = (sequence1, sequence2) | |
} | |
public struct Iterator: IteratorProtocol { | |
internal var iterator1: Type1.Iterator | |
internal var iterator2: Type2.Iterator | |
internal var reachedEnd = false | |
internal init (_ iterator1: Type1.Iterator, _ iterator2: Type2.Iterator) { | |
(self.iterator1, self.iterator2) = (iterator1, iterator2) | |
} | |
public mutating func next() -> (Type1.Iterator.Element, Type2.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 var zip: (shortest: Zip.ShortestSequence, longest: Zip.LongestSequence) { | |
return (shortest: Zip.ShortestSequence(self.first, self.second), longest: Zip.LongestSequence(self.first, self.second)) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment