在一个可遍历的foreach方法中获取当前元素的索引?

假设我有两个数组:

val ar1 = Array[String]("1", "2", "3") val ar2 = Array[String]("1", "2", "3", "4") 

现在,对于ar1每个元素,我想首先将该元素与ar2的相应元素连接起来,然后打印结果。 一种方法可能是这样的:

 List.range(0, ar1.size).foreach(i => println(ar1(i)+ar2(i))) 

如果有一个foreach变体可以让我直接使用ar1的索引,而不是先构造整数列表,那将会更好。

也许有更好的办法?

一个非常方便的方法是使用元组上的zipped方法。 把两个集合,出来两个参数的function!

 (ar1,ar2).zipped.foreach((x,y) => println(x+y)) 

这样既方便又快速,因为你不需要构build一个元组来存储每一对(就像你使用(ar1 zip ar2) ),这样你就不得不再次分解了。 当两个集合中较短的一个耗尽时,两种forms的拉链停止。

如果你有更复杂的东西(例如你需要对索引进行math计算),那么规范的解决scheme是在索引中进行压缩:

 ar1.zipWithIndex.foreach{ case(x,i) => println(x+ar2(i)) } 

你正在使用的方法更快速和紧凑地完成如下,一个可以是有用的:

 ar1.indices.foreach(i => println(ar1(i)+ar2(i))) 

尽pipe这只有在第一次收集不再是第二次时才有效。 你也可以指定你的范围explcitly:

 (0 until (ar1.size min ar2.size)).foreach(i => println(ar1(i)+ar2(i))) 

解决这个问题。 (你可以看到为什么zipzipped是首选的,除非你所做的事情太复杂了,以至于无法轻松工作。)

如果它不是一个平行的集合(通常它不是,除非你调用.par ),也可以,但不build议,跟踪一个可变的variables:

 { var i=-1; ar1.foreach{ x => i += 1; println(x+ar2(i)) } } 

有必要的情况下数量非常有限(例如,如果您想跳过或回溯一些其他collections品)。 如果你可以避免这样做,你通常会得到更容易推理的代码。

这就是你如何在一个惯用的斯卡拉循环索引:

 scala> List("A", "B", "C").zipWithIndex foreach { case(el, i) => | println(i + ": " + el) | } 0: A 1: B 2: C 

这里是惯用的斯卡拉方式来做你想在你的代码中实现的:

 scala> val arr1 = Array("1", "2", "3") arr1: Array[java.lang.String] = Array(1, 2, 3) scala> val arr2 = Array("1", "2", "3", "4") arr2: Array[java.lang.String] = Array(1, 2, 3, 4) scala> (arr1, arr2).zipped.map(_ + _) foreach println 11 22 33 

我没有机会去testing,但是这个应该可以做到:

 ar1.zip(ar2).foreach(x => println(x._1 +x._2)) 

zip将做到这一点:

 ar1 zip ar2 foreach { p => println(p._1 + p._2) } 

这将产生:

 11 22 33 

注意你不需要[String]genericstypes,会被编译器传递:

 val ar1 = Array("1", "2", "3") val ar2 = Array("1", "2", "3", "4")