问题:
你要遍历一个有序集合,同时你又想访问一个循环计数器,但最重要的是你真的不须要手动建立这个计数器。
解决方案:
使用zipWithIndex或者zip方法来自动地建立一个计数器,假设你有一个有序集合days,那么你能够使用zipWithIndex和counter来打印带有计数器的集合元素:app
scala> val days = Array("Sunday", "Monday", "Tuesday", "Wednesday","Thursday", "Friday", "Saturday") days: Array[String] = Array(Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday) scala> days.zipWithIndex.foreach{case(day,count) => println(s"$count is $day")} 0 is Sunday 1 is Monday 2 is Tuesday 3 is Wednesday 4 is Thursday 5 is Friday 6 is Saturday
一样,你能够使用for循环来打印计数器和集合元素ui
scala> for((day,count) <- days.zipWithIndex) { | println(s"$count is $day") | } 0 is Sunday 1 is Monday 2 is Tuesday 3 is Wednesday 4 is Thursday 5 is Friday 6 is Saturday
zipWithIndex的计数器都是从0开始,若是你想指定开始的值,那么你能够使用zip Stream:spa
scala> for((day,count) <- days.zip(Stream from 1)) { | println(s"$count is $day") | } 1 is Sunday 2 is Monday 3 is Tuesday 4 is Wednesday 5 is Thursday 6 is Friday 7 is Saturday
当有序集合调用zipWithIndex的时候,它会返回一个有序的二元组集合:scala
scala> val list = List("a", "b", "c") list: List[String] = List(a, b, c) scala> list.zipWithIndex res3: List[(String, Int)] = List((a,0), (b,1), (c,2))
由于zipWithIndex是在一个已经存在的有序集合的基础上创建一个新的有序集合,你能够在调用zipWithIndex以前调用view:code
就像上面这个例子里面看到的,它在原有的List基础上建立了一个lazy view,因此这个元组集合并不被会被建立,直到它被调用的那一刻。正因有这种特性,咱们推荐在调用zipWithIndex以前先调用view方法。blog
zip和zipWithIndex方法都返回一个有序二元组集合。所以,你的foreach方法也能够写成下面这样,虽然这比起解决方案中的方法,可读性略差。ip
scala> days.zipWithIndex.foreach(d => println(s"${d._2} is ${d._1}")) 0 is Sunday 1 is Monday 2 is Tuesday 3 is Wednesday 4 is Thursday 5 is Friday 6 is Saturday
在以前的例子中咱们曾经见过,能够经过一个for循环加range来建立这个计数器:element
scala> val fruits = Array("apple", "banana", "orange") fruits: Array[String] = Array(apple, banana, orange) scala> for (i <- 0 until fruits.size) println(s"element $i is ${fruits(i)}") element 0 is apple element 1 is banana element 2 is orange