由于Scala没有for带索引的旧Java样式循环,
// does not work
val xs = Array("first", "second", "third")
for (i=0; i<xs.length; i++) {
println("String #" + i + " is " + xs(i))
}
Run Code Online (Sandbox Code Playgroud)
我们如何有效地迭代,而不使用var?
你可以做到这一点
val xs = Array("first", "second", "third")
val indexed = xs zipWithIndex
for (x <- indexed) println("String #" + x._2 + " is " + x._1)
Run Code Online (Sandbox Code Playgroud)
但列表遍历了两次 - 效率不高.
Did*_*ont 121
比遍历两次更糟糕的是,它创建了一对中间数组.你可以用view.当你这样做时collection.view,你可以认为后续调用在迭代期间是懒惰的.如果你想找回一个完全实现的完整系列,你可以force在最后打电话.这将是无用的和昂贵的.所以将代码更改为
for((x,i) <- xs.view.zipWithIndex) println("String #" + i + " is " + x)
Run Code Online (Sandbox Code Playgroud)
Kip*_*ros 66
有人提到Scala 确实有for循环语法:
for (i <- 0 until xs.length) ...
Run Code Online (Sandbox Code Playgroud)
或者干脆
for (i <- xs.indices) ...
Run Code Online (Sandbox Code Playgroud)
但是,你也要求提高效率.事实证明,Scala的for语法实际上是更高阶的方法,如语法糖map,foreach等.因此,在某些情况下,这些循环可以是低效的,例如如何优化,内涵和循环在Scala呢?
(好消息是Scala团队正在努力改进这一点.这是bug跟踪器中的问题:https://issues.scala-lang.org/browse/SI-4633)
为了获得最高效率,可以使用while循环,或者,如果您坚持删除var尾递归的用法:
import scala.annotation.tailrec
@tailrec def printArray(i: Int, xs: Array[String]) {
if (i < xs.length) {
println("String #" + i + " is " + xs(i))
printArray(i+1, xs)
}
}
printArray(0, Array("first", "second", "third"))
Run Code Online (Sandbox Code Playgroud)
请注意,可选 @tailrec注释对于确保方法实际上是尾递归非常有用.Scala编译器将尾递归调用转换为等效于while循环的字节代码.
mis*_*tor 18
还有一种方法:
scala> val xs = Array("first", "second", "third")
xs: Array[java.lang.String] = Array(first, second, third)
scala> for (i <- xs.indices)
| println(i + ": " + xs(i))
0: first
1: second
2: third
Run Code Online (Sandbox Code Playgroud)
om-*_*nom 13
实际上,scala具有索引的旧Java样式循环:
scala> val xs = Array("first","second","third")
xs: Array[java.lang.String] = Array(first, second, third)
scala> for (i <- 0 until xs.length)
| println("String # " + i + " is "+ xs(i))
String # 0 is first
String # 1 is second
String # 2 is third
Run Code Online (Sandbox Code Playgroud)
其中0 until xs.length或者0.until(xs.length)是一个RichInt返回方法Range适于循环.
此外,您可以尝试循环to:
scala> for (i <- 0 to xs.length-1)
| println("String # " + i + " is "+ xs(i))
String # 0 is first
String # 1 is second
String # 2 is third
Run Code Online (Sandbox Code Playgroud)
这个怎么样?
val a = Array("One", "Two", "Three")
a.foldLeft(0) ((i, x) => {println(i + ": " + x); i + 1;} )
Run Code Online (Sandbox Code Playgroud)
输出:
0: One
1: Two
2: Three
Run Code Online (Sandbox Code Playgroud)
scala 中的循环非常简单。创建您选择的任何数组。
val myArray = new Array[String](3)
myArray(0)="0";
myArray(1)="1";
myArray(2)="2";
Run Code Online (Sandbox Code Playgroud)
循环类型,
for(data <- myArray)println(data)
for (i <- 0 until myArray.size)
println(i + ": " + myArray(i))
Run Code Online (Sandbox Code Playgroud)
我有以下方法
object HelloV2 {
def main(args: Array[String]) {
//Efficient iteration with index in Scala
//Approach #1
var msg = "";
for (i <- args.indices)
{
msg+=(args(i));
}
var msg1="";
//Approach #2
for (i <- 0 until args.length)
{
msg1 += (args(i));
}
//Approach #3
var msg3=""
args.foreach{
arg =>
msg3 += (arg)
}
println("msg= " + msg);
println("msg1= " + msg1);
println("msg3= " + msg3);
}
}
Run Code Online (Sandbox Code Playgroud)