|
/// In contrast to the Swift Zip2Sequence this type will not omit values that don't have a partner due to Sequence length mismatch. |
|
/// The Iterator will iterate over `SafeZip2Sequence.Value`. |
|
public struct SafeZip2Sequence<Sequence1: Sequence, Sequence2: Sequence> { |
|
fileprivate let sequence1: Sequence1 |
|
fileprivate let sequence2: Sequence2 |
|
} |
|
|
|
extension SafeZip2Sequence: Sequence { |
|
/// An iterator for `SafeZip2Sequence`. |
|
public struct Iterator { |
|
fileprivate var iterator1: Sequence1.Iterator |
|
fileprivate var iterator2: Sequence2.Iterator |
|
} |
|
|
|
/// An element of `SafeZip2Sequence`. |
|
public enum Element { |
|
case pair(first: Sequence1.Element, second: Sequence2.Element) |
|
case first(Sequence1.Element) |
|
case second(Sequence2.Element) |
|
} |
|
|
|
public func makeIterator() -> Iterator { |
|
return Iterator(iterator1: sequence1.makeIterator(), iterator2: sequence2.makeIterator()) |
|
} |
|
} |
|
|
|
extension SafeZip2Sequence.Iterator: IteratorProtocol { |
|
|
|
/// Advances to the next element and returns it, or `nil` if no next element |
|
/// exists. |
|
/// |
|
/// Once `nil` has been returned, all subsequent calls return `nil`. |
|
public mutating func next() -> SafeZip2Sequence.Element? { |
|
let value1 = iterator1.next() |
|
let value2 = iterator2.next() |
|
return Element(first: value1, second: value2) |
|
} |
|
} |
|
|
|
|
|
fileprivate extension SafeZip2Sequence.Element { |
|
|
|
init?(first: Sequence1.Element?, second: Sequence2.Element?) { |
|
switch (first, second) { |
|
case let (first?, second?): |
|
self = .pair(first: first, second: second) |
|
case let (first?, nil): |
|
self = .first(first) |
|
case let (nil, second?): |
|
self = .second(second) |
|
default: |
|
return nil |
|
} |
|
} |
|
} |
|
|
|
public func safeZip<Sequence1: Sequence, Sequence2: Sequence>(_ sequence1: Sequence1, _ sequence2: Sequence2) -> SafeZip2Sequence<Sequence1, Sequence2> { |
|
return SafeZip2Sequence(sequence1: sequence1, sequence2: sequence2) |
|
} |
|
|
|
public func safeZip<Sequence1, Sequence2>(_ sequence1: Sequence1, _ sequence2: Sequence2, execute: (SafeZip2Sequence<Sequence1, Sequence2>.Element) -> Void) { |
|
for value in safeZip(sequence1, sequence2) { |
|
execute(value) |
|
} |
|
} |
|
|
|
public extension Sequence { |
|
func mySafeZip<S: Sequence>(_ sequence: S) -> SafeZip2Sequence<Self, S> { |
|
return safeZip(self, sequence) |
|
} |
|
|
|
func mySafeZip<S: Sequence>(_ sequence: S, execute: (SafeZip2Sequence<Self, S>.Element) -> Void) { |
|
return safeZip(self, sequence, execute: execute) |
|
} |
|
} |