Zip2 that uses optionals for unequal lengths, plus using it to implement equal for sequences
public struct ZipOuter2<S1: SequenceType, S2: SequenceType>: SequenceType { | |
private let _s1: S1 | |
private let _s2: S2 | |
init(_ s1: S1, _ s2: S2) { | |
_s1 = s1 | |
_s2 = s2 | |
} | |
public typealias Generator = GeneratorOf<(S1.Generator.Element?, S2.Generator.Element?)> | |
public func generate() -> Generator { | |
// the requirement to never call .next() a second time | |
// after it returns nil complicates this a bit | |
var g1: S1.Generator? = _s1.generate() | |
var g2: S2.Generator? = _s2.generate() | |
return GeneratorOf { | |
switch(g1?.next(),g2?.next()) { | |
case (.None,.None): return nil // both generators are exhausted | |
case let (.Some(x),.None): g2 = nil; return (x,nil) | |
case let (.None,.Some(y)): g1 = nil; return (nil,y) | |
case (let x, let y): return (x,y) | |
} | |
} | |
} | |
} | |
// the std lib equal that takes a comparator requires the sequences contain the same | |
// type, which shouldn't be necessary since the comparator could cater for that | |
public func equal<S1: SequenceType, S2: SequenceType>(a1: S1, a2: S2, isEquivalent: (S1.Generator.Element, S2.Generator.Element) -> Bool) -> Bool { | |
for pair in ZipOuter2(a1, a2) { | |
switch pair { | |
case (.None,.None): assertionFailure("should never happen") | |
case (.None, .Some): return false | |
case (.Some, .None): return false | |
case let (.Some(x),.Some(y)): if !isEquivalent(x,y) { return false } | |
} | |
} | |
return true | |
} | |
let eqIntString: (Int,String)->Bool = { i,s in s.toInt().map { $0 == i } ?? false } | |
equal([1,2,3], ["1","2","3"], eqIntString) | |
equal(1...3, ["1","2","3"], eqIntString) | |
equal([Int](),[String](), eqIntString) | |
!equal([1,2,3,4], ["1","2","3"], eqIntString) | |
!equal([1,2,3], ["1","2","3","4"], eqIntString) | |
!equal([1,1,3], ["1","2","3"], eqIntString) | |
!equal([1,2,3], ["1","3","3"], eqIntString) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment