Skip to content

Instantly share code, notes, and snippets.

@huynhjl
Created September 10, 2010 14:18
Show Gist options
  • Save huynhjl/573703 to your computer and use it in GitHub Desktop.
Save huynhjl/573703 to your computer and use it in GitHub Desktop.
LookAheadIterator
/**
* An iterator that allows retrieving elements ahead without advancing the iterator.
*/
class LookAheadIterator[T](underlying:Iterator[T]) extends BufferedIterator[T] {
private val queue = collection.mutable.Queue[T]()
/**
* Returns a new iterator to read ahead element.
* Elements from underlying are queued so that they can be returned by the
* current iterator.
*/
def lookahead() = queue.iterator ++ new Iterator[T] {
def hasNext = underlying.hasNext
def next() = { val x = underlying.next(); queue += x; x }
}
def hasNext = underlying.hasNext || !queue.isEmpty
def next() = if (!queue.isEmpty) queue.dequeue() else underlying.next()
def head = if (queue.isEmpty) {
val x = underlying.next(); queue += x; x
} else {
queue.head
}
def headOption = if (hasNext) Some(head) else None
def takeUntil(p: T => Boolean): Iterator[T] = {
val buf = collection.mutable.ArrayBuffer[T]()
val elems = lookahead().takeWhile(t => !p(t))
buf ++= elems
(1 to buf.size) foreach { _ => next() }
buf.iterator
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment