Skip to content

Instantly share code, notes, and snippets.

@wheelerlaw
Last active February 26, 2018 17:01
Show Gist options
  • Save wheelerlaw/9e55973102570d68da17c2e7dd8295b2 to your computer and use it in GitHub Desktop.
Save wheelerlaw/9e55973102570d68da17c2e7dd8295b2 to your computer and use it in GitHub Desktop.
import scala.collection.{AbstractIterator, Iterator}
import scala.collection.Iterator.empty
object ImplicitIteratorExtensions{
implicit final class InclusiveIterator[A](it: Iterator[A]){
/**
* The actual function to act upon the iterator. Emuluates a "do-while" loop. In other words, it will stop iterating on
* predicte failure, but will include that last result as a part of the iterator.
* @param predicate {A => Boolean} - A function that is evaluated on each result from the parent iterator.
* @return
*/
@inline def takeDoWhile(predicate: A => Boolean): Iterator[A] = new AbstractIterator[A] {
private var continue: Boolean = true
/**
* True if the parent iterator is true AND the predicate has not already failed.
* @return
*/
def hasNext: Boolean = it.hasNext && continue
/**
* If the predicate fails, we return that item, but mark this iterator to fail on the next iteration.
* @return
*/
def next(): A = {
if(continue){
val result: A = it.next()
if (!predicate(result)) continue = false
result // Give the result even if the predicate fails, but only once.
}else{
empty.next()
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment