第十章 Scala 容器基礎(十六):flatMap一個把flatten和map結合起來的方法

Problem

    當你第一次來到Scala世界的時候,flatMap放方法看起來是很特別的,因此你須要理解他是如何工做的,還有它是應用在什麼地方的。
函數

Solution

    在你調用map方法後緊接着調用flatten方法的狀況下,你就能夠嘗試調用flatMap來解決這個問題了。知足以下狀況:scala

  • 使用map方法來從原集合基礎上建立一個新的集合code

  • map方法的返回結果是一個嵌套集合,或者元素爲Some和Nonethree

  • 你在map方法後緊接着調用了flatten方法字符串

    若是你的程序正好符合上面的狀況,那麼你就是可使用flatMap來代替collection.map.flatten了
it

    下面這個例子中,你會看到如何使用flatMap來處理一個Option。在這個例子中,咱們要計算集合中數字類型元素的和。又一個問題:數字都是字符串類型的,而且好多元素並非數字,也不能轉換爲Int型。先來看下這個集合:io

scala> val bag = List("1", "2", "three", "4", "one hundred seventy five")
bag: List[String] = List(1, 2, three, 4, one hundred seventy five)

    爲了解決這個問題,你開始建立一個字符串到整形的轉換函數來返回Some[Int]或者None:event

scala> def toInt(in: String): Option[Int] = {
     |   try {
     |     Some(Integer.parseInt(in.trim))
     |   } catch {
     |     case e: Exception => None
     |   }
     | }
toInt: (in: String)Option[Int]

    下面咱們來看看使用flatMap的效果:class

scala> bag.flatMap(toInt).sum
res23: Int = 7

scala> bag.flatMap(toInt)
res24: List[Int] = List(1, 2, 4)

Discussion

    爲了看清楚flatMap是如何工做的,咱們吧這個問題拆分紅幾小步。首先,你要知道當你調用map方法會發生什麼:基礎

scala> bag.map(toInt)
res26: List[Option[Int]] = List(Some(1), Some(2), None, Some(4), None)

    map方法使toInt函數做用在了集合的每一個元素上,而且返回了一組Some[Int]和None的集合。可是sum方法要做用在List[Int]上,怎麼辦?上節踢桃flatten方法能夠把集合中Some裏的數據展開,而後拋棄None。

scala> bag.map(toInt).flatten
res27: List[Int] = List(1, 2, 4)

    此次咱們就可以調用sum方法了:

scala> bag.map(toInt).flatten.sum
res28: Int = 7

    哇,我看到了map.flatten的結構,我想到了「flat map」,因此我就可使用flatMap方法了:

scala> bag.flatMap(toInt).sum
res23: Int = 7

    一旦你得道了一個原始集合,而且想把它轉換爲List[Int]。你能夠調用豐富的集合方法來獲取你想要的結果:

scala> bag.flatMap(toInt).filter(_ > 1)
res29: List[Int] = List(2, 4)

scala> bag.flatMap(toInt).takeWhile(_ < 4)
res30: List[Int] = List(1, 2)

scala> bag.flatMap(toInt).partition(_ > 3)
res31: (List[Int], List[Int]) = (List(4),List(1, 2))
相關文章
相關標籤/搜索