字符串上的地图与FlatMap

Kev*_*ith 25 scala map

听听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

  • 如何在没有查看实现的情况下猜测或者尝试将`string`映射转换为`IndexSeq [String]`并且`flatten`将其转换回`String`.这听起来像我每次将`map`或`flatMap`应用于scala中的某些数据结构时我都需要尝试一下或查看它的实现来理解它的行为,是这样吗?如果是这样一个好的设计(明确的代码明智)? (2认同)

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将a String视为一个序列Char,它会将生成的字符串列表展平为一系列字符(Seq[Char]).
flatMap是的组合mapflatten,所以它首先运行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)


Art*_*mGr 7

map函数c => ("." + c)接受一个char并返回一个String.这就像拿一个List并返回一个列表列表.flatMap将其展平.

如果要返回char而不是String,则不需要将结果展平,例如"abc".map(c => (c + 1).toChar)返回"bcd".