9
scala> List(List(1), List(2), List(3), List(4))
res18: List[List[Int]] = List(List(1), List(2), List(3), List(4))

scala> res18.flatten
res19: List[Int] = List(1, 2, 3, 4)

scala> res18.flatMap(identity)
res20: List[Int] = List(1, 2, 3, 4)

这两个功能有什么区别吗?什么时候适合使用其中一种?有什么取舍吗?

4

3 回答 3

13

您可以查看flatMap(identity)map(identity).flatten. (当然它不是这样实现的,因为它需要两次迭代)。

map(identity)给你相同的集合,所以最终它与 only 相同flatten

我个人会坚持使用flatten,因为它更短/更容易理解并且旨在准确地做到这一点。

于 2014-11-18T22:33:18.337 回答
6

从概念上讲,结果没有区别......flatMap需要更多时间来产生相同的结果......

我将用一个更实际的例子来展示它flatMapmap&然后flattenflatten

对象测试扩展 App {
  //平面图
  println(timeElapsed(List(List(1, 2, 3, 4), List(5, 6, 7, 8)).flatMap(identity)))
  // 映射然后展平
  println(timeElapsed(List(List(1, 2, 3, 4), List(5, 6, 7, 8)).map(identity).flatten))
  // 展平
  println(timeElapsed(List(List(1, 2, 3, 4), List(5, 6, 7, 8)).flatten))

  /**
   * 时间流逝
   */
  def timeElapsed[T](block: => T): T = {
    val start = System.nanoTime()
    val res = 块
    val totalTime = System.nanoTime - 开始
    println("经过的时间:%1d 纳秒".format(totalTime))
    资源
  }
}


重复几次后都执行相同flatMap的结果flatten

结论:flatten有效

经过时间:2915949 纳秒
列表(1、2、3、4、5、6、7、8)
经过时间:1060826 纳秒
列表(1、2、3、4、5、6、7、8)
经过时间:81172 纳秒
列表(1、2、3、4、5、6、7、8)
于 2017-08-14T10:23:11.570 回答
3

从概念上讲,没有区别。实际上,flatten效率更高,并传达了更清晰的意图。

一般不identity直接使用。它更适用于作为参数传入或设置为默认值的情况。编译器可以对其进行优化,但您冒着对每个元素进行多余函数调用的风险。

flatMap当您需要执行 a map(使用除 之外的函数)时,您将使用identity紧跟 a flatten

于 2014-11-18T22:36:48.283 回答