在一个可遍历的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)))
解决这个问题。 (你可以看到为什么zip
和zipped
是首选的,除非你所做的事情太复杂了,以至于无法轻松工作。)
如果它不是一个平行的集合(通常它不是,除非你调用.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")