Since Scala does not have old Java style for
loops with index,
// does not work
val xs = Array("first", "second", "third")
for (i=0; i<xs.length; i++) {
println("String #" + i + " is " + xs(i))
}
How can we iterate efficiently, and without using var
's?
You could do this
val xs = Array("first", "second", "third")
val indexed = xs zipWithIndex
for (x <- indexed) println("String #" + x._2 + " is " + x._1)
but the list is traversed twice - not very efficient.
A simple and efficient way, inspired from the implementation of
transform
in SeqLike.scalaMuch worse than traversing twice, it creates an intermediary array of pairs. You can use
view
. When you docollection.view
, you can think of subsequent calls as acting lazily, during the iteration. If you want to get back a proper fully realized collection, you callforce
at the end. Here that would be useless and costly. So change your code toIt has been mentioned that Scala does have syntax for
for
loops:or simply
However, you also asked for efficiency. It turns out that the Scala
for
syntax is actually syntactic sugar for higher order methods such asmap
,foreach
, etc. As such, in some cases these loops can be inefficient, e.g. How to optimize for-comprehensions and loops in Scala?(The good news is that the Scala team is working on improving this. Here's the issue in the bug tracker: https://issues.scala-lang.org/browse/SI-4633)
For utmost efficiency, one can use a
while
loop or, if you insist on removing uses ofvar
, tail recursion:Note that the optional
@tailrec
annotation is useful for ensuring that the method is actually tail recursive. The Scala compiler translates tail-recursive calls into the byte code equivalent of while loops.How about this?
Output:
I have the following approaches
One more way: