我正试图了解Scala中的flatMap
实现。基于Scala编程中的定义
函数返回元素列表作为其右参数。它将函数应用于每个列表并返回所有函数结果的串联。
现在要了解这一点,我有以下实现
val listwords = List(List("abc"),List("def"),List("ghi"))
val res2 = listwords flatMap (_+"1")
println(res2) //output- List(L, i, s, t, (, a, b, c, ), 1, L, i, s, t, (, d, e, f, ), 1, L, i, s, t, (, g, h, i, ), 1)
val res3 = listwords flatMap (_.apply(0).toCharArray())
println(res3) //output- List(a, b, c, d, e, f, g, h, i)
看一下令我发疯的第一个输出,为什么List[List[String]]
会被视为List[String]
?
毕竟回答上面的问题,有人请帮我执行一个操作,需要选择每个内部的第一个字符串的第一个字符,并产生List[Char]
。因此,考虑到listwords
,我希望输出为List('a', 'd', 'g')
。
答案 0 :(得分:1)
List("abc") + "1"
相当于List("abc").toString + "1"
,因此它返回字符串" List(a,b,c)1"。 List.flatMap
的类型是
flatMap[B](f: (A) ⇒ GenTraversableOnce[B]): List[B]
,您的函数的类型为(List[String] => String)
。 String
扩展了GenTraversableOnce[Char]
,因此您的结果列表的类型为List[Char]
。
答案 1 :(得分:1)
代码listwords flatMap (_+"1")
可以重写为listwords flatMap (list => list.toString + "1")
。所以你基本上使用toString方法将所有列表转换为字符串。
要获取第一个字符,您可以使用以下表达式:
listwords.flatMap(_.headOption).flatMap(_.headOption)
答案 2 :(得分:0)
_+"1"
没有做你认为它正在做的事情。
它被解释为list: List[String] => list.+("1")
由于List[String]
不包含此类方法,因此编译器会在范围内查找隐式转换。它找到了any2stringadd
。 (有关隐式转换的更多信息,请参阅http://docs.scala-lang.org/tutorials/tour/implicit-conversions)
implicit final class any2stringadd[A](private val self: A) extends AnyVal {
def +(other: String): String = String.valueOf(self) + other
}
list: List[String] => list.+("1")
现在变成
list: List[String] => new any2stringadd(list).+("1")
返回String.valueOf(list) + "1"
答案 3 :(得分:0)
首先,您需要了解map
和flatMap
方法之间的区别。它们都迭代一些容器并将函数文字应用于每个元素。不同之处在于flatMap
正在进行一项额外的操作:它会使容器的结构变得扁平。还有一种方法允许您只进行展平及其调用flatten
(因此flatMap
相当于map
操作后跟flatten
操作) 。您必须记住的第二件事是您正在修改(映射)嵌套列表,因此您还需要嵌套map
/ flatMap
个调用。这些例子应该向你澄清所有这些:
scala> val wordLists = List(List("abc"),List("de"),List("f"), List())
wordLists: List[List[String]] = List(List(abc), List(de), List(f), List())
scala> val words = wordsLists.flatten
words: List[String] = List(abc, de, f)
scala> val replacedWordLists = wordsLists.map(_ => List("xyz"))
replacedWordLists: List[List[String]] = List(List(xyz), List(xyz), List(xyz), List(xyz))
scala> val replacedWords = wordsLists.map(_ => List("xyz")).flatten // Equivalent: wordsLists.flatMap(_ => List("xyz"))
replacedWords: List[String] = List(xyz, xyz, xyz, xyz)
scala> val upperCaseWordLists = wordsLists.map(_.map(_.toUpperCase))
upperCaseWordLists: List[List[String]] = List(List(ABC), List(DE), List(F), List())
scala> val upperCaseWords = wordsLists.map(_.map(_.toUpperCase)).flatten // Equivalent: wordsLists.flatMap(_.map(_.toUpperCase))
upperCaseWords: List[String] = List(ABC, DE, F)
scala> val optionalFirstLetterLists = wordLists.map(_.map(_.headOption))
optionalFirstLetterLists: List[List[Option[Char]]] = List(List(Some(a)), List(Some(d)), List(Some(f)), List())
scala> val optionalFirstLetters = wordLists.map(_.map(_.headOption)).flatten // Equivalent: wordLists.flatMap(_.map(_.headOption))
optionalFirstLetters: List[Option[Char]] = List(Some(a), Some(d), Some(f))
scala> val firstLetterLists = wordLists.map(_.map(_.headOption).flatten) // Equivalent: wordLists.map(_.flatMap(_.headOption))
firstLetterLists: List[List[Char]] = List(List(a), List(d), List(f), List())
scala> val firstLetters = wordLists.map(_.flatMap(_.headOption)).flatten // Equivalent: wordLists.flatMap(_.flatMap(_.headOption))
firstLetters: List[Char] = List(a, d, f)