Instantly share code, notes, and snippets.

Embed
What would you like to do?
LazyDropLast
extension Sequence {
func lazyDropLast(_ n: Int) -> AnySequence<Element> {
precondition(n >= 0, "Can't drop a negative number of elements from a sequence")
return AnySequence<Element>({ () -> AnyIterator<Element> in
var iterator = self.makeIterator()
if n == 0 { return AnyIterator(iterator) }
var ringBuffer = Array<Element>()
ringBuffer.reserveCapacity(n)
for _ in 0..<n {
guard let next = iterator.next() else { return AnyIterator([].makeIterator()) }
ringBuffer.append(next)
}
var index = 0
return AnyIterator({ () -> Element? in
guard let next = iterator.next() else { return nil }
defer { index += 1 }
defer { ringBuffer[index % n] = next }
return ringBuffer[index % n]
})
})
}
}
print(Array((0...10).lazyDropLast(0)))
print(Array((0...10).lazyDropLast(1)))
print(Array((0...10).lazyDropLast(5)))
print(Array((0...10).lazyDropLast(11)))
print(Array((0...10).lazyDropLast(20)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment