【问题标题】:Is there any difference between flatten and flatMap(identity)?flatten 和 flatMap(identity) 之间有什么区别吗?
【发布时间】:2015-01-16 06:44:23
【问题描述】:
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)

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

【问题讨论】:

    标签: scala functional-programming flatmap


    【解决方案1】:

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

    map(identity) 给你的集合是一样的,所以最后还是和flatten 一样。

    我个人会坚持使用flatten,因为它更短/更容易理解,并且专门为此而设计。

    【讨论】:

      【解决方案2】:

      从概念上讲,结果没有区别...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)) 资源 } }

      flatMapflatten 在重复多次后执行相同的结果

      结论: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)

      【讨论】:

        【解决方案3】:

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

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

        当您需要执行map(具有identity 以外的功能)时,您将使用flatMap,然后紧跟flatten

        【讨论】:

        • 最后一句(“你会使用..”)具有误导性,flatmap 不能总是用map + flatten 替换,它通常传达不同的计算
        • @Chirlo,我认为你错了,但如果我错了,我愿意承认。可以举个反例吗?
        • 使用map + flatten,您将始终获得与原始元素数量相同的List。使用flatmap,您可以进行更多操作,例如list.flatmap( x => if (x > 2 ) List(x,x,x,x) else List())。这将产生(来自 OPs 示例):List(3,3,3,3,4,4,4,4)。你可以用flatMap来实现filtertakeWhile....,这是map+flatten做不到的
        • 您使用map+flatten 的第一个示例是list.map(x=>if (x>2) List(x,x,x,x) else List()).flattenfilterlist.map(x => if (pred(x)) List(x) else List()).flatten
        • 哦,好吧,我误解了这个例子,但是你可以得到into situations,因为scala的签名是flatmapCanBuildFrom)。
        猜你喜欢
        • 2021-03-14
        • 2010-12-27
        • 2013-09-13
        • 2017-04-05
        • 2014-09-18
        • 2015-06-14
        • 2011-05-23
        • 2011-02-15
        相关资源
        最近更新 更多