为什么要使用展平?与flatMap有何不同?

时间:2018-10-30 10:30:32

标签: scala flatmap

在Scala中,为什么我们使用import fetch from '../../../../core/fetch'; export default sessionId => async (dispatch, getState) => { console.log(sessionId); console.log(evt.target.value); }; ?与flatten有何不同? 涉及期货的示例将非常有用。

1 个答案:

答案 0 :(得分:3)

flatten不涉及flatMap的“地图”部分。可以将其视为只是扁平化的嵌套结构。 Option[Option[Int]]变成Option[Int]List[List[Int]]变成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)