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 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
}
```

Finally, remember the **Scaladoc** is your friend.

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.