听听Scala中的函数式编程原理的集合讲座,我看到了这个例子:
scala> val s = "Hello World"
scala> s.flatMap(c => ("." + c)) // prepend each element with a period
res5: String = .H.e.l.l.o. .W.o.r.l.d
Run Code Online (Sandbox Code Playgroud)
然后,我很好奇为什么奥德斯基先生没有在map这里使用.但是,当我尝试地图时,我得到的结果与我预期的不同.
scala> s.map(c => ("." + c))
res8: scala.collection.immutable.IndexedSeq[String] = Vector(.H, .e, .l, .l, .o,
". ", .W, .o, .r, .l,
Run Code Online (Sandbox Code Playgroud)
我期望上面的调用返回一个String,因为我正在处理map,即将函数应用于"序列"中的每个项目,然后返回一个新的"序列".
但是,我可以执行map而不是flatmap一个List[String]:
scala> val sList = s.toList
sList: List[Char] = List(H, e, l, l, o, , W, o, r, l, d)
scala> sList.map(c => "." + c)
res9: List[String] = List(.H, .e, .l, .l, .o, ". ", .W, .o, .r, .l, .d)
Run Code Online (Sandbox Code Playgroud)
为什么IndexedSeq[String]调用mapString 的返回类型?
fre*_*oma 30
这种行为的原因是,为了将"map"应用于String,Scala将该字符串视为一系列chars(IndexedSeq[String]).这是您通过映射调用获得的结果,对于所述序列的每个元素,应用该操作.由于Scala将字符串视为要应用的序列map,因此map返回.
flatMap然后简单地调用flatten该序列,然后将其"转换"回String
Von*_*onC 14
您还有一个有趣的" Scala flatMap示例集合 ",其中第一个示例说明了flatMap和之间的区别map:
scala> val fruits = Seq("apple", "banana", "orange")
fruits: Seq[java.lang.String] = List(apple, banana, orange)
scala> fruits.map(_.toUpperCase)
res0: Seq[java.lang.String] = List(APPLE, BANANA, ORANGE)
scala> fruits.flatMap(_.toUpperCase)
res1: Seq[Char] = List(A, P, P, L, E, B, A, N, A, N, A, O, R, A, N, G, E)
Run Code Online (Sandbox Code Playgroud)
相当不同吧?
因为flatMap将aString视为一个序列Char,它会将生成的字符串列表展平为一系列字符(Seq[Char]).
flatMap是的组合map和flatten,所以它首先运行map上的序列,然后运行flatten,从而示出的结果.您可以通过运行地图然后展平自己来看到这一点:
scala> val mapResult = fruits.map(_.toUpperCase)
mapResult: Seq[String] = List(APPLE, BANANA, ORANGE)
scala> val flattenResult = mapResult.flatten
flattenResult: Seq[Char] = List(A, P, P, L, E, B, A, N, A, N, A, O, R, A, N, G, E)
Run Code Online (Sandbox Code Playgroud)
map函数c => ("." + c)接受一个char并返回一个String.这就像拿一个List并返回一个列表列表.flatMap将其展平.
如果要返回char而不是String,则不需要将结果展平,例如"abc".map(c => (c + 1).toChar)返回"bcd".
| 归档时间: |
|
| 查看次数: |
26377 次 |
| 最近记录: |