Skip to content

Instantly share code, notes, and snippets.

@natecook1000
Created October 12, 2017 21:59
Show Gist options
  • Select an option

  • Save natecook1000/7a602f3aa4742295e2d9cdc9952efc4b to your computer and use it in GitHub Desktop.

Select an option

Save natecook1000/7a602f3aa4742295e2d9cdc9952efc4b to your computer and use it in GitHub Desktop.
struct Zip2Collection<C1: Collection, C2: Collection> : Collection {
enum Index: Comparable {
case index(C1.Index, C2.Index)
case end
static func <(lhs: Index, rhs: Index) -> Bool {
switch (lhs, rhs) {
case (.end, _): return false
case (_, .end): return true
case let (.index(l, _), .index(r, _)):
return l < r
}
}
static func ==(lhs: Index, rhs: Index) -> Bool {
switch (lhs, rhs) {
case (.end, .end): return true
case (.end, _), (_, .end): return false
case let (.index(l, _), .index(r, _)):
return l == r
}
}
}
var startIndex: Index {
return .index(c1.startIndex, c2.startIndex)
}
var endIndex: Index {
return .end
}
subscript(index: Index) -> (C1.Element, C2.Element) {
guard case let .index(i1, i2) = index else {
fatalError("Can't subscript with endIndex")
}
return (c1[i1], c2[i2])
}
func index(after i: Index) -> Index {
guard case let .index(i1, i2) = i else {
fatalError("Can't advance beyond endIndex")
}
let (r1, r2) = (c1.index(after: i1), c2.index(after: i2))
if r1 == c1.endIndex || r2 == c2.endIndex {
return .end
}
return .index(r1, r2)
}
let c1: C1
let c2: C2
}
func zip<C1, C2>(_ c1: C1, _ c2: C2) -> Zip2Collection<C1, C2> {
return Zip2Collection(c1: c1, c2: c2)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment