【问题标题】:scala Iterable#map vs. Iterable#flatMapscala Iterable#map 与 Iterable#flatMap
【发布时间】:2010-11-06 18:47:45
【问题描述】:

IterablemapflatMap函数有什么区别?

【问题讨论】:

    标签: scala monads scala-collections


    【解决方案1】:

    以上都是正确的,但还有一件事很方便:flatMapList[Option[A]] 转换为List[A],删除任何向下钻取到NoneOption。这是超越使用null 的关键概念突破。

    【讨论】:

    • 噢,这是我从未想过的 Option 的另一个好技巧。我只是有一个方法返回一个或多个事物的列表,从未见过Option.toList 方法: List( Some( "foo" ), None, Some( "bar" ) ).flatMap( _.toList )
    • 或者甚至更好,将Option.toIterator 与 Tristan 的方法一起使用,这样您就不会在必要时遍历整个列表。
    【解决方案2】:

    这里有一个很好的解释:

    http://www.codecommit.com/blog/scala/scala-collections-for-the-easily-bored-part-2

    以列表为例:

    地图的签名是:

    map [B](f : (A) => B) : List[B]
    

    而 flatMap 是

    flatMap [B](f : (A) => Iterable[B]) : List[B]
    

    所以 flatMap 接受一个类型 [A] 并返回一个可迭代类型 [B] 而 map 接受一个类型 [A] 并返回一个类型 [B]

    这也会让您了解 flatmap 将“扁平化”列表。

    val l  = List(List(1,2,3), List(2,3,4))
    
    println(l.map(_.toString)) // changes type from list to string
    // prints List(List(1, 2, 3), List(2, 3, 4))
    
    println(l.flatMap(x => x)) // "changes" type list to iterable
    // prints List(1, 2, 3, 2, 3, 4)
    

    【讨论】:

    • 有趣的是,根据一元公理,l flatMap { x => x }精确等同于l.flatten。 FlatMap 相当于 Scala 的一元 bind 操作(在 Haskell 中为 >>=)。我发现它对诸如 Option 之类的非集合单子最有用。当与集合结合使用时,它对于实现“嵌套映射循环”最为有用,并返回一个集合作为结果。
    • 说得好。与 if(x != null 和 x.foo != null) 之类的一堆语句相比,Options 的链接要好得多。 blog.lostlake.org/index.php?/archives/… 详细讨论这个
    • println(l.flatMap(x => x)) 这不再起作用,需要像这样使用 flatMap :aperiodic.net/phil/scala/s-99/p07.scala
    【解决方案3】:

    来自scaladoc

    • 地图

    返回可迭代的结果 从应用给定的函数 f 到 此可迭代对象的每个元素。

    • 平面地图

    应用给定的函数 f 到这个可迭代的每个元素,然后 连接结果。

    【讨论】:

    • 我正在寻找更多的分析/解释。
    • 好的,所以将您的问题更改为更具体。说出你已经知道的,以及你需要澄清的。
    • 我更喜欢你简短的评论。
    • 我也是,但我认为谨慎是勇气的更好部分:)
    【解决方案4】:
    lines.map(line => line split "\\W+") // will return a list of arrays of words
    lines.flatMap(line => line split "\\W+") // will return a list of words
    

    你可以在理解中更好地看到这一点:

    for {line <- lines
         word <- line split "\\W+"}
    yield word.length
    

    这翻译成:

    lines.flatMap(line => line.split("\\W+").map(word => word.length))
    

    for 中的每个迭代器都将被翻译成“flatMap”,除了最后一个被翻译成“map”的迭代器。这样,您不会返回嵌套集合(blah、blah、blah 缓冲区的数组列表),而是返回一个平面集合。由正在生成的元素形成的集合——在本例中为整数列表。

    【讨论】:

      【解决方案5】:

      看这里: http://www.codecommit.com/blog/scala/scala-collections-for-the-easily-bored-part-2

      “搜索 flatMap”——那里有一个很好的解释。 (基本上它是“扁平化”和“地图”的组合——来自其他语言的特征)。

      【讨论】:

        猜你喜欢
        • 2019-02-13
        • 2012-01-04
        • 1970-01-01
        • 2010-11-07
        • 2011-07-26
        • 1970-01-01
        • 1970-01-01
        • 2017-10-14
        • 2020-09-03
        相关资源
        最近更新 更多