Skip to content

Instantly share code, notes, and snippets.

@erikerlandson
Created September 5, 2014 02:21
Show Gist options
  • Save erikerlandson/eb7edf947771abb33ff6 to your computer and use it in GitHub Desktop.
Save erikerlandson/eb7edf947771abb33ff6 to your computer and use it in GitHub Desktop.
variations I tried
/** Advances this iterator past the first ''n'' elements, or the length of the iterator, whichever is smaller.
*
* @param n the number of elements to drop
* @return an iterator which produces all values of the current iterator, except
* it omits the first `n` values.
* @note Reuse: $consumesAndProducesIterator
*/
def drop(n: Int): Iterator[A] = slice(n, Int.MaxValue)
/** Creates an iterator returning an interval of the values produced by this iterator.
*
* @param from the index of the first element in this iterator which forms part of the slice.
* @param until the index of the first element following the slice.
* @return an iterator which advances this iterator past the first `from` elements using `drop`,
* and then takes `until - from` elements, using `take`.
* @note Reuse: $consumesAndProducesIterator
*/
def slice(from: Int, until: Int): Iterator[A] = {
val lo = from max 0
var toDrop = lo
while (toDrop > 0 && self.hasNext) {
self.next()
toDrop -= 1
}
class AI(val iter: Iterator[A]) extends AbstractIterator[A] {
private var remaining = until - lo
def hasNext = remaining > 0 && iter.hasNext
def next(): A =
if (remaining > 0) {
remaining -= 1
iter.next()
}
else empty.next()
}
new AI(self)
}
/** Advances this iterator past the first ''n'' elements, or the length of the iterator, whichever is smaller.
*
* @param n the number of elements to drop
* @return an iterator which produces all values of the current iterator, except
* it omits the first `n` values.
* @note Reuse: $consumesAndProducesIterator
*/
def drop(n: Int): Iterator[A] = slice(n, Int.MaxValue)
/** Creates an iterator returning an interval of the values produced by this iterator.
*
* @param from the index of the first element in this iterator which forms part of the slice.
* @param until the index of the first element following the slice.
* @return an iterator which advances this iterator past the first `from` elements using `drop`,
* and then takes `until - from` elements, using `take`.
* @note Reuse: $consumesAndProducesIterator
*/
trait SlicedIterator[+A] extends Iterator[A] {
protected def self: Iterator[A] = this
override def slice(from: Int, until: Int): Iterator[A] = {
val lo = from max 0
var toDrop = lo
while (toDrop > 0 && self.hasNext) {
self.next()
toDrop -= 1
}
class AI[+A](val iter: Iterator[A]) extends AbstractIterator[A] with SlicedIterator[A] {
private var remaining = until - lo
def hasNext = remaining > 0 && iter.hasNext
def next(): A =
if (remaining > 0) {
remaining -= 1
iter.next()
}
else Iterator.empty.next()
}
new AI(self)
}
}
def slice(from: Int, until: Int): Iterator[A] = {
val lo = from max 0
var toDrop = lo
while (toDrop > 0 && self.hasNext) {
self.next()
toDrop -= 1
}
class AI(val iter: Iterator[A]) extends AbstractIterator[A] with SlicedIterator[A] {
private var remaining = until - lo
def hasNext = remaining > 0 && iter.hasNext
def next(): A =
if (remaining > 0) {
remaining -= 1
iter.next()
}
else empty.next()
}
new AI(self)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment