I'd like to create an Iterator
that gets its next element by (repeatedly) evaluating an expression, and I want the expression to be able to return a certain value to terminate it.
The only thing I've found like this is Iterator.continually(), which seems to be infinite. It's important that the expression should not be evaluated until next()
is called on the Iterator
.
Is there a way to get this behaviour?
for example:
def getNext = {
// some complicated code
val next = ... // either a STOP value or a real value to be returned by the iterator
}
val myIter = Iterator.continually(getNext) // want this to stop at some point
Iterator.continually
is usually combined with takeWhile
:
var count = 0
def complexCompute(): Int = { count +=1; println("eval " + count); count }
val iter = Iterator.continually { complexCompute() }
iter.takeWhile(_ < 3).foreach(println)
Which prints:
eval 1
1
eval 2
2
eval 3
So if the condition that determines whether the computation should continue can be evaluated outside the computation then this works pretty well.
Basically I guess I'm saying Iterator.continually(getNext()).takeWhile(_ != certainValue)
will achieve what you're trying to do. It's lazily evaluated.
Have you looked at scala.collection.immutable.Stream? It's purpose it to create a sequence like object where the next element is lazily evaluated. It can be finite or infinite.
For example:
Welcome to Scala version 2.9.0.final (Java HotSpot(TM) Client VM, Java 1.6.0_24).
Type in expressions to have them evaluated.
Type :help for more information.
scala> import collection.immutable._
import collection.immutable._
scala> def next(i: Int): Stream[Int] = Stream.cons(i*i, next(i*i))
next: (i: Int)scala.collection.immutable.Stream[Int]
scala> val stream = next(2)
stream: scala.collection.immutable.Stream[Int] = Stream(4, ?)
scala> stream.find(_ > 1000)
res0: Option[Int] = Some(65536)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With