Iterable
的map
函数和flatMap
函数有什么区别?
以上内容都是真实的,但还有一件非常方便的事情: flatMap
将一个 List[Option[A]]
转换为 List[A]
,并移除所有深入到 None
的 Option
。这对于超越使用 null
是一个关键的概念突破。
这里有一个相当不错的解释:
http://www.codecommit.com/blog/scala/scala-collections-for-the-easily-bored-part-2
以列表为例:
Map 的签名如下:
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中单子绑定操作(在Haskell中为>>=)的等价物。我发现它在非集合的单子上最有用,比如Option。与集合一起使用时,它最常用于实现“嵌套映射循环”,返回一个集合作为结果。 - Daniel Spiewaklines.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循环中更好地理解这个:
for {line <- lines
word <- line split "\\W+"}
yield word.length
这意味着:
lines.flatMap(line => line.split("\\W+").map(word => word.length))
每个for循环中的迭代器都会被转换为“flatMap”,除了最后一个迭代器,它会被转换为“map”。这样,不会返回嵌套的集合(例如列表中包含数组或缓冲区等),而是返回一个平坦的集合。在这种情况下,由yield生成的元素组成了一个列表,其中包含整数。
请看这里:http://www.codecommit.com/blog/scala/scala-collections-for-the-easily-bored-part-2
"搜索flatMap" - 这里有一个非常好的解释。(基本上它是来自其他语言的 "flatten" 和 "map" 的组合)。
Option.toList
方法:List( Some( "foo" ), None, Some( "bar" ) ).flatMap( _.toList )
- Tristan JuricekOption.toIterator
,这样你就不必在不必要的情况下遍历整个列表。 - Jonathan Schneider