Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save khanlou/21c0666d317219b234ebf7eb04b1733a to your computer and use it in GitHub Desktop.

Select an option

Save khanlou/21c0666d317219b234ebf7eb04b1733a to your computer and use it in GitHub Desktop.
Bidirectional Iterator
extension BidirectionalCollection {
func makeBidirectionalIterator() -> BidirectionalIterator<Self, Index> {
return BidirectionalIterator<Self, Index>(collection: self)
}
}
let a = [1, 2, 3, 4]
var i = a.makeBidirectionalIterator()
i.next() // => 1?
i.next() // => 2?
i.previous() // => 1?
i.next() // => 2?
i.next() // => 3?
i.next() // => 4?
i.next() // => nil
i.next() // => nil
i.previous() // => 4?
i.previous() // => 3?
i.previous() // => 2?
i.previous() // => 1?
i.previous() // => nil
struct BidirectionalIterator<B, I> where B: BidirectionalCollection, B.Index == I {
let collection: B
var lastGivenIndex: I? = nil
init(collection: B) {
self.collection = collection
}
mutating func next() -> B.Iterator.Element? {
guard let lastGivenIndex = lastGivenIndex else {
self.lastGivenIndex = collection.startIndex
return collection.first
}
if lastGivenIndex >= collection.index(before: collection.endIndex) {
self.lastGivenIndex = collection.endIndex
return nil
}
self.lastGivenIndex = collection.index(after: lastGivenIndex)
return self.lastGivenIndex.map({ collection[$0] })
}
mutating func previous() -> B.Iterator.Element? {
guard let lastGivenIndex = lastGivenIndex else {
return nil
}
if lastGivenIndex <= collection.startIndex {
self.lastGivenIndex = collection.startIndex
return nil
}
self.lastGivenIndex = collection.index(before: lastGivenIndex)
return self.lastGivenIndex.map({ collection[$0] })
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment