第十章 Scala 容器基礎(十):使用for循環來遍歷一個集合

Problem

    我想使用for循環來遍歷容器的全部元素,或者經過for yield來建立一個新的集合。app

Solution

    你能夠使用for循環遍歷全部的Traversable類型(基本上全部的sequency均可以):函數

scala> val fruits = Traversable("apple", "banana", "orange")
fruits: Traversable[String] = List(apple, banana, orange)

scala> for (f <- fruits) println(f)
apple
banana
orange

scala> for (f <- fruits) println(f.toUpperCase)
APPLE
BANANA
ORANGE

    若是你的循環體代碼很長,那麼你一樣能夠像正常使用for循環同樣,執行多行的代碼塊:oop

scala> for (f <- fruits) {
     |   val s = f.toUpperCase
     |   println(s)
     | }
APPLE
BANANA
ORANGE

    使用一個計數器看成下標來訪問一個集合:ui

scala> val fruits = IndexedSeq("apple", "banana", "orange")
fruits: IndexedSeq[String] = Vector(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

    你一樣能夠使用zipWithIndex方法來遍歷集合的時候獲取當前元素的索引:scala

scala> for ((elem, count) <- fruits.zipWithIndex) {println(s"element $count is $elem")}
element 0 is apple
element 1 is banana
element 2 is orange

    生成一個計數器來獲取集合元素下標的另外一個方法是zip stream:code

scala> for ((elem,count) <- fruits.zip(Stream from 1)) {println(s"element $count is $elem")}
element 1 is apple
element 2 is banana
element 3 is orange

scala> for ((elem,count) <- fruits.zip(Stream from 0)) {println(s"element $count is $elem")}
element 0 is apple
element 1 is banana
element 2 is orange
The for/yield construct

    當你想經過一個現有的集合,對其元素進行加工後生成一個新的集合,那麼就能夠使用for yield這樣形式:索引

scala> val fruits = Array("apple", "banana", "orange")
fruits: Array[String] = Array(apple, banana, orange)

scala> val newArray = for (e <- fruits) yield e.toUpperCase
newArray: Array[String] = Array(APPLE, BANANA, ORANGE)

    再看一下這個例子的另外兩種形式,一個是當for循環方法體是多行的時候,另外一個形式是當你想複用yield後面的操做函數時:ip

scala> val newArray = for (e <- fruits) yield {
     |   val s = e.toUpperCase
     |   s
     | }
newArray: Array[String] = Array(APPLE, BANANA, ORANGE)

scala> def upper(s: String):String = {s.toUpperCase}
upper: (s: String)String

scala> val newArray = for (e <- fruits) yield upper(e)
newArray: Array[String] = Array(APPLE, BANANA, ORANGE)
Map

    使用for循環來遍歷一個Map一樣也是很是方便的:element

scala> val names = Map("fname" -> "Ed", "lname" -> "Chigliak")
names: scala.collection.immutable.Map[String,String] = Map(fname -> Ed, lname -> Chigliak)

scala> for ((k,v) <- names) println(s"key: $k, value: $v")
key: fname, value: Ed
key: lname, value: Chigliak

Discussion

    When using a for loop, the <- symbol can be read as 「in,」 so the following statement can be read as 「for i in 1 to 3, do ...」:get

for (i <- 1 to 3) { // more code here ...

    在使用for循環來遍歷一個集合元素的時候,咱們一樣能夠添加if字句來對元素進行過濾:

for {
    file <- files
    if file.isFile //file是一個文件
    if file.getName.endsWith(".txt") //file後綴名爲.txt
} doSomething(file)
相關文章
相關標籤/搜索