scala - 为什么我们使用扁平化?它与平面地图有什么不同?
问题描述
在 scala 中,我们为什么使用flatten
? 它与 有何不同flatMap
?涉及期货的示例将非常有用。
解决方案
flatten
不涉及flatMap
. 把它想象成只是扁平化的嵌套结构。AnOption[Option[Int]]
变成只是 anOption[Int]
或 aList[List[Int]]
变成 a List[Int]
(通过连接各个列表的元素)。
相反,映射会改变结构中包含的元素。所以
Some(4).map(_ + 1) // evaluates to Some(5)
有时传递给的函数会map
返回底层结构本身的实例。假设您有一个可选的 id 并且如果设置了它,您想在数据库中查找它而不知道是否存在记录,因此您的函数也返回一个Option
:
val optionalId: Option[String] = ???
def getRecord(id: String): Option[Record] = ???
val naiveResult: Option[Option[Record]] = optionalId.map(getRecord)
这通常不是你想要的。本质上你有一个Option[Record]
并且不需要额外的嵌套。所以你会flatten
在之后打电话map
:
optionalId.map(getRecord).flatten // evaluates to an Option[Record]
现在flatMap
基本上是两种方法的结合:
optionalId.flatMap(getRecord) // also yields an Option[Record]
的应用flatMap
不仅限于收藏,而且更普遍。它派上用场的另一个例子是期货。假设我们没有可选的 id 而是一个 Future[String] ,它表示最终将产生 id 的计算。我们还有一个方法可以为我们Future[Record]
提供一个 id。我们现在可以像这样获得Future[Record]
一个Future[String]
:
val idFuture: Future[String] = ???
def getRecord(id: String): Future[Record] = ???
val recordFuture: Future[Record] = idFuture.flatMap(getRecord)
推荐阅读
- hamiltonian-cycle - 使用 LKH-2,是否可以提取所有哈密顿循环?
- git - 在重新调整其分支后重新打开关闭的拉取请求
- php - Doctrine Query Builder 和 Where With 或 Where
- java - 转换集合
列出 > 在特定条件下使用 stream() - java - DatePickerFragment.newInstance() 无法从静态上下文 android studio 中引用
- laravel - 目标 [...] 在构建 [...] 时不可实例化
- string - 我们如何在 Bigquery 表中将数字转换为 12 小时时间格式
- visual-studio - 在 Visual Studio 2019 解决方案中运行 PowerShell 脚本
- python - 编码和解码 - 希伯来语字符串看起来像乱码 - 来自 Teradata 的 Python 3
- if-statement - if 语句中的 if 是关键字吗?