听听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]
调用map
String 的返回类型?
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 次 |
最近记录: |