Search code examples
scalaiteratorlazy-evaluationextendenrich-my-library

Scala, extending the iterator


Im looking to extended the iterator to create a new method takeWhileInclusive, which will operate like takeWhile but include the last element.

My issue is what is best practice to extend the iterator to return a new iterator which I would like to be lazy evaluated. Coming from a C# background I normal use IEnumerable and use the yield keyword, but such an option doesn't appear to exist in Scala.

for example I could have

List(0,1,2,3,4,5,6,7).iterator.map(complex time consuming algorithm).takeWhileInclusive(_ < 6)

so in this case the takeWhileInclusive would only have resolve the predicate on the values until I get the a result greater than 6, and it will include this first result

so far I have:

object ImplicitIterator {
  implicit def extendIterator(i : Iterator[Any]) = new IteratorExtension(i)
}

class IteratorExtension[T <: Any](i : Iterator[T]) {
  def takeWhileInclusive(predicate:(T) => Boolean) = ?
}

Solution

  • This is one case where I find the mutable solution superior:

    class InclusiveIterator[A](ia: Iterator[A]) {
      def takeWhileInclusive(p: A => Boolean) = {
        var done = false
        val p2 = (a: A) => !done && { if (!p(a)) done=true; true }
        ia.takeWhile(p2)
      }
    }
    implicit def iterator_can_include[A](ia: Iterator[A]) = new InclusiveIterator(ia)