第十章 Scala 容器基础(十一):使用zip或者zipWithIndex来创建一个循环计数器

原创
2016/04/12 14:26
阅读数 3.6K

Problem

    你要遍历一个有序集合,同时你又想访问一个循环计数器,但最重要的是你真的不需要手动创建这个计数器。

Solution

    使用zipWithIndex活着zip方法来自动地创建一个计数器,假设你有一个有序集合days,那么你可以使用zipWithIndex和counter来打印带有计数器的集合元素:

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循环来打印计数器和集合元素

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:

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

Discussion

    当有序集合调用zipWithIndex的时候,它会返回一个有序的二元组集合:

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:

scala> val zwv = list.view.zipWithIndex
zwv: scala.collection.SeqView[(String, Int),Seq[_]] = SeqViewZ(...)

    就像上面这个例子里面看到的,它创建了一个lazy view在原有的List基础上,所以这个元组集合并不被会被创建,直到它被调用的那一刻。正因有这种特性,我们推荐在调用zipWithIndex之前先调用view方法。

    zip和zipWithIndex方法都返回一个有序二元祖集合。因此,你的foreach方法也可以写成下面这样,虽然这比起解决方案中的方法,可读性略差。

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来创建这个计数器:

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


展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
1
分享
返回顶部
顶部