你想要對一個原有集合的元素經過某種算法進行處理,而後生成一個新的集合。算法
使用for/yield結構外加你的算法就能夠從一個原有集合建立一個新的集合。首先咱們要有一個集合app
scala> val a = Array(1, 2, 3, 4, 5) a: Array[Int] = Array(1, 2, 3, 4, 5)
使用for/yield建立一個集合的拷貝:ui
scala> for(e <- a) yield e res12: Array[Int] = Array(1, 2, 3, 4, 5)
你能夠建立一個新的集合,經過對原有集合的每一個元素翻倍,也能夠把原集合的元素變爲1/2編碼
scala> for(e <- a) yield e * 2 res14: Array[Int] = Array(2, 4, 6, 8, 10) scala> for(e <- a) yield e / 2 res16: Array[Int] = Array(0, 1, 1, 2, 2)
把一組字符串轉化爲大寫:spa
scala> for(fruit <- fruits) yield fruit.toUpperCase res17: scala.collection.immutable.Vector[String] = Vector(APPLE, BANANA, LIME, ORANGE)
你的算法能夠返回任何你想要的集合,下面咱們來把一個集合轉化爲2元組:scala
scala> for (i <- 0 until fruits.length) yield (i, fruits(i)) res18: scala.collection.immutable.IndexedSeq[(Int, String)] = Vector((0,apple), (1,banana), (2,lime), (3,orange))
下面這個算法,返回原集合元素與元素長度組成的二元祖:
code
scala> for(fruit <- fruits) yield (fruit, fruit.length) res20: scala.collection.immutable.Vector[(String, Int)] = Vector((apple,5), (banana,6), (lime,4), (orange,6))
定義一個case class Person,而後根據一組姓名來建立Person集合:字符串
scala> case class Person (name: String) defined class Person scala> val friends = Vector("Mark", "Regina", "Matt") friends: scala.collection.immutable.Vector[String] = Vector(Mark, Regina, Matt) scala> for (f <- friends) yield Person(f) res21: scala.collection.immutable.Vector[Person] = Vector(Person(Mark), Person(Regina), Person(Matt))
你能夠在for/yield語句中添加if來對原有集合元素進行過濾:it
scala> val x = for (e <- fruits if e.length < 6) yield e.toUpperCase x: scala.collection.immutable.Vector[String] = Vector(APPLE, LIME)
for循環和yield的結合能夠看做是for表達式活着序列表達式。它從一個原有集合的基礎上返回一個新的集合。若是你是第一個使用for/yield結構,它會讓你想到有一個桶活着臨時區域在裏邊。每個來自原有集合的元素被轉化而後執行yield操做,被加入到桶中。而後當循環結束的時候,桶中的全部元素被yield表達式返回。
io
一般狀況下,原集合類型決定了for/yield返回新集合的類型。若是你使用一個ArrayBuffer做爲原集合,那麼新集合確定也是ArrayBuffer:
scala> val fruits = scala.collection.mutable.ArrayBuffer("apple", "banana") fruits: scala.collection.mutable.ArrayBuffer[String] = ArrayBuffer(apple, banana) scala> val x = for (e <- fruits) yield e.toUpperCase x: scala.collection.mutable.ArrayBuffer[String] = ArrayBuffer(APPLE, BANANA)
一個List返回一個List:
scala> val fruits = "apple" :: "banana" :: "orange" :: Nil fruits: List[String] = List(apple, banana, orange) scala> val x = for (e <- fruits) yield e.toUpperCase x: List[String] = List(APPLE, BANANA, ORANGE)
當你給for添加一個grards(警衛),而且想把代碼寫成多行表達式,推薦的編碼風格是使用花括號而不是圓括號:
scala> val fruits = Vector("apple", "banana", "lime", "orange") fruits: scala.collection.immutable.Vector[String] = Vector(apple, banana, lime, orange) scala> for { | e <- fruits | if e.length < 6 | } yield e.toUpperCase res25: scala.collection.immutable.Vector[String] = Vector(APPLE, LIME)
這樣代碼更具可讀性,尤爲是當你給for添加多個grards(警衛)的時候。
當我第一次開始使用Scal的時候a,我老是使用for/yield表達式來作這樣的集合轉換工做,可是有一個我發現我可使用更簡便的方式達到一樣的目標,那就是map方法。下一節,咱們就來介紹如何使用map方法來吧一個集合轉化爲另外一個集合。