Scala - 地图和 flatMap 之间的区别

Ryo*_*han 2 functional-programming scala

谁能教我map和的财产用例flatMap的属性用例吗?

万一Option,我知道这两个方法都有各自的签名,def map(A => B): Option[B]并且def flatMap(A => Option[B]): Option[B]

因此,我可以通过两种方式获得一些价值:

scala> val a = Some(1).map(_ + 2)
a: Option[Int] = Some(3)

scala> val a2 = Some(1).flatMap(n => Some(n + 2))
a2: Option[Int] = Some(3)
Run Code Online (Sandbox Code Playgroud)

当我写一个方法时:def plusTwo(n: Int),有什么区别

def plusTwo(n: Int): Int = n + 2
Some(1).map(plusTwo)
Run Code Online (Sandbox Code Playgroud)

def plusTwo(n: Int): Option[Int] = Some(n + 2)
Some(1).flatMap(plusTwo)
Run Code Online (Sandbox Code Playgroud)

flatMap可以转换为 for 理解,并且几乎所有方法都返回Option包装的值是不是更好?

小智 8

假设您有一个列表:

val names = List("Benny", "Danna", "Tal")
names: List[String] = List(Benny, Danna, Tal)
Run Code Online (Sandbox Code Playgroud)

现在让我们以您的例子为例。假设我们有一个返回选项的函数:

def f(name: String) = if (name contains "nn") Some(name) else None
Run Code Online (Sandbox Code Playgroud)

map 函数的工作原理是对列表中的每个元素应用一个函数:

names.map(name => f(name))
List[Option[String]] = List(Some(Benny), Some(Danna), None)
Run Code Online (Sandbox Code Playgroud)

另一方面,flatMap 应用一个函数,该函数返回列表中每个元素的序列,并将结果展平到原始列表中

names.flatMap(name => f(name))
List[String] = List(Benny, Danna)
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,flatMap 删除了 Some/None 层,只保留了原始列表。