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))
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
}
Thank you all very much.