Hi there.

I’m newbie to Scala.

I wrote such for-loops:

``````var a = 0
var b = 0
for (x <- 0 until 100) {
for (y <- 0 until 100) {
if (arr(x)(y) == z) {
a = x
b = y
}
}
}
``````

How to rewrite loops in Scala way?

Hi @Xapadi and welcome to the community!

It seems you want the last pair of indexes where the value of a matrix is equal to something, but only looking in the first `100` indexes.

Assuming all that is correct and that you are sure your matrix has a size at least equal to `100 x 100` you may do this:

``````def lastIndexOfOcurrence[A](m: ArraySeq[ArraySeq[A]])(elem: A): Option[(Int, Int)] =
Iterator
.range(start = 99, end = -1, step = -1)
.map { i =>
val j = m(i).lastIndexWhere(_ == elem)
if (j == -1) None
else Some(i -> j)
} collectFirst {
case Some((i, j)) => i -> j
}
``````

I think it is fine to use `for` loops in Scala when they improve code readability. However, you should avoid `var`s if you can. To reproduce exactly the result you get from your loop without `var`s you could write:

``````    val (a, b) = (
for (x <- 0 until 100;
y <- 0 until 100 if arr(x)(y) == z) yield (x, y))
.lastOption
.getOrElse((0, 0))
``````

That assumes that you want to have `a=0` and `b=0` when `arr` has no element `z`. If you would like to know if `z` was found you can stop at `lastOption`.

Without `for` loops, an alternate to what @BalmungSan suggested:

``````    val (a, b) =
arr.zipWithIndex
.map { case (ax, x) => (x, ax.lastIndexOf(z)) }
.findLast { case (x, y) => y >= 0 }
.getOrElse((0, 0))
``````
2 Likes

Note, those are NOT for loops, those are for comprehensions.

Also, in general, it is better to delay the `getOrElse` outside of your function, that way the caller is free to pick the best default or to compose with other options; of course, there are exceptions.
Finally, I think it would be more readable to split that in multiple statements; like:

``````def lastIndexOfOccurrence[A](m: ArraySeq[ArraySeq[A]])(elem: A): Option[(Int, Int)] = {
val indexesOfOccurrence = for {
x <- 0 until 100
y <- 0 until 100
if m(x)(y) == z
} yield (x, y)

indexesOfOccurrence.lastOption
}
``````
3 Likes

Thank you all very much.