Skip to content

Instantly share code, notes, and snippets.

@danielctull
Created October 13, 2020 08:57
Show Gist options
  • Save danielctull/2856fb53525810db1da898d0c1e098ac to your computer and use it in GitHub Desktop.
Save danielctull/2856fb53525810db1da898d0c1e098ac to your computer and use it in GitHub Desktop.
Another idea for the intersperse index.
extension Intersperse: Collection where Base: Collection {
public struct Index: Comparable {
enum Representation {
case end
case element(Base.Index)
case separator(Base.Index)
}
let representation: Representation
public static func == (lhs: Index, rhs: Index) -> Bool {
switch (lhs.representation, rhs.representation) {
case (.end, .end): return true
case let (.element(lhs), .element(rhs)): return lhs == rhs
case let (.separator(lhs), .separator(rhs)): return lhs == rhs
default: return false
}
}
public static func < (lhs: Index, rhs: Index) -> Bool {
switch (lhs.representation, rhs.representation) {
case (.end, .end): return false
case (_, .end): return true
case (.end, _): return false
case let (.element(lhs), .element(rhs)): return lhs < rhs
case let (.element(lhs), .separator(rhs)): return lhs <= rhs
case let (.separator(lhs), .separator(rhs)): return lhs < rhs
case let (.separator(lhs), .element(rhs)): return lhs < rhs
}
}
}
public var count: Int {
Swift.max(base.count * 2 - 1, 0)
}
public var startIndex: Index {
Index(representation: .element(base.startIndex))
}
public var endIndex: Index {
Index(representation: .end)
}
public func index(after i: Index) -> Index {
switch i.representation {
case .element(let index) where base.index(after: index) < base.endIndex:
return Index(representation: .separator(index))
case .element:
return endIndex
case .end:
fatalError()
case .separator(let index):
return Index(representation: .element(base.index(after: index)))
}
}
public subscript(position: Index) -> Element {
switch position.representation {
case .end: fatalError()
case .element(let index): return base[index]
case .separator: return separator
}
}
}
extension Intersperse: BidirectionalCollection
where Base: BidirectionalCollection
{
public func index(before i: Index) -> Index {
switch i.representation {
case .end:
return Index(representation: .element(base.index(before: base.endIndex)))
case .element(let index):
return Index(representation: .separator(base.index(before: index)))
case .separator(let index):
return Index(representation: .element(index))
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment