You can do this with a combination of a filter and an external var. Here is an example:

var nextValidVal = 0
for (i <- 0 to 99; if i >= nextValidVal) {
  var amountToSkip = 0
  // Whatever this loop is for
  nextValidVal = if (amountToSkip > 0) i + amountToSkip + 1 else nextValidVal

So in the main body of your loop, you can set amountToSkip to n according to your conditions. The next n values of i´s sequence will be skipped.

If your sequence is pulled from some other kind of sequence, you could do it like this

var skip = 0
for (o <- someCollection if { val res = skip == 0; skip = if (!res) skip - 1 else 0; res } ) {
  // Do stuff

If you set skip to a positive value in the body of the loop, the next n elements of the sequence will be skipped.

Of course, this is terribly imperative and side-effecty. I would look for other ways to to this where ever possible, by mapping or filtering or folding the original sequence.


You could implement your own stream to reflect step, for example:

import scala.collection.immutable.Stream
import ForStream._
object Test {
  def main(args: Array[String]): Unit = {
    val range = 0 to 20 by 1 withVariableStep; // in case you like definition through range
    //val range = ForStream(0,20,1) // direct definition
    for (i<- range) {
      range.step = range.step + 1

object ForStream{
  implicit def toForStream(range: Range): ForStream = new ForStreamMaster(range.start, range.end,range.step)
  def apply(head:Int, end:Int, step:Int) = new ForStreamMaster(head, end,step)

abstract class ForStream(override val head: Int, val end: Int, var step: Int) extends Stream[Int] {
  override val tailDefined = false
  override val isEmpty = head > end
  def withVariableStep = this

class ForStreamMaster(_head: Int, _end: Int, _Step: Int) extends ForStream(_head, _end,_Step){
  override def tail = if (isEmpty) Stream.Empty else new ForStreamSlave(head + step, end, step, this)

class ForStreamSlave(_head: Int, _end: Int, _step: Int, val master: ForStream) extends ForStream(_head, _end,_step){
  override def tail = if (isEmpty) Stream.Empty else new ForStreamSlave(head + master.step, end, master.step, master)

This prints:







You can define ForStream from Range with implicits, or define it directly. But be carefull:

  1. You are not iterating Range anymore!
  2. Stream should be immutable, but step is mutable!

Also as @om-nom-nom noted, this might be better implemented with recursion


Why not use the do-while loop?

var x = 0;
if(condition){change x to something else}
else{something else}
}while(some condition for x)

Related Query

More Query from same tag