scala Iterable #map与Iterable#flatMap

Lan*_*uhn 58 monads scala scala-collections

有什么区别mapflatMap功能Iterable

kik*_*obo 56

上面的都是真的,但有一两件事是很方便: flatMap打开一个List[Option[A]]List[A],与任何Option该钻下来None,除去.这是超越使用的关键概念突破null.

  • 噢,这是我从未想过的选项的另一个好方法.我只是有一个方法返回一个或多个东西的列表,从未见过`Option.toList`方法:List(Some("foo"),None,Some("bar")).flattMap(_.toList) (3认同)

agi*_*all 44

这是一个很好的解释:

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

以列表为例:

地图的签名是:

map [B](f : (A) => B) : List[B]
Run Code Online (Sandbox Code Playgroud)

和flatMap是

flatMap [B](f : (A) => Iterable[B]) : List[B]
Run Code Online (Sandbox Code Playgroud)

因此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)
Run Code Online (Sandbox Code Playgroud)

  • 有趣的是,根据monadic公理,`l flatMap {x => x}`*精确*等同于`l.flatten`.FlatMap是Scala相当于monadic`bind`操作(>> =在Haskell中).我发现它对非集合monad(如Option)最有用.与集合结合使用时,它对于实现"嵌套映射循环"非常有用,因此返回集合作为结果. (12认同)

ska*_*man 8

来自scaladoc:

  • 地图

返回通过将给定函数f应用于此iterable的每个元素而得到的iterable.

  • flatMap

将给定的函数f应用于此iterable的每个元素,然后连接结果.

  • 我更喜欢你的讽刺评论. (5认同)

Dan*_*ral 8

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
Run Code Online (Sandbox Code Playgroud)

你可以更好地理解这一点:

for {line <- lines
     word <- line split "\\W+"}
yield word.length
Run Code Online (Sandbox Code Playgroud)

这转化为:

lines.flatMap(line => line.split("\\W+").map(word => word.length))
Run Code Online (Sandbox Code Playgroud)

内部的每个迭代器都将被翻译成"flatMap",除了最后一个,它将被翻译成"地图".这样,您可以返回一个扁平集合,而不是返回嵌套集合(一个blah,blah,blah缓冲区数组的列表).由产生的元素组成的集合 - 在这种情况下是整数列表.