scala中的平面映射行为

scala中的平面映射行为,scala,flatmap,Scala,Flatmap,我正试图掌握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

我正试图掌握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]

在回答了上述问题之后,请有人帮助我执行一个操作,该操作需要从每个内部字符串的第一个字符串中选择第一个字符,并生成一个
列表[Char]
。因此,给定
listwords
,我希望输出是
List('a','d','g')
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]
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]

代码
listwords flatMap(+“1”)
可以重写为
listwords flatMap(list=>list.toString+“1”)
。所以您基本上使用toString方法将所有列表转换为字符串

要获取第一个字符,可以使用以下表达式:

listwords.flatMap(_.headOption).flatMap(_.headOption)

代码
listwords flatMap(+“1”)
可以重写为
listwords flatMap(list=>list.toString+“1”)
。所以您基本上使用toString方法将所有列表转换为字符串

要获取第一个字符,可以使用以下表达式:

listwords.flatMap(_.headOption).flatMap(_.headOption)
。+“1”
没有做你认为它在做的事情

它被解释为
list:list[String]=>list.+(“1”)

由于
List[String]
不包含这样的方法,编译器将在作用域中查找隐式转换。它查找
any2stringad
。(有关隐式转换的详细信息,请参见)

隐式final类any2stringadd[A](private val self:A)扩展AnyVal{
def+(其他:字符串):字符串=String.valueOf(self)+其他
}
list:list[String]=>list.+(“1”)

现在变成

list:list[String]=>newany2stringad(list)。+(“1”)

它返回
String.valueOf(list)+“1”
.+“1”
没有做您认为它正在做的事情

它被解释为
list:list[String]=>list.+(“1”)

由于
List[String]
不包含这样的方法,编译器将在作用域中查找隐式转换。它查找
any2stringad
。(有关隐式转换的详细信息,请参见)

隐式final类any2stringadd[A](private val self:A)扩展AnyVal{
def+(其他:字符串):字符串=String.valueOf(self)+其他
}
list:list[String]=>list.+(“1”)

现在变成

list:list[String]=>newany2stringad(list)。+(“1”)


它返回
String.valueOf(list)+“1”
首先,您需要了解
map
flatMap
方法之间的区别。它们都迭代某个容器,并对每个元素应用函数文本。不同之处在于,
flatMap
正在进行另一个操作:它将容器的结构展平。还有一种方法允许您只进行展平,它被称为
flatte
(因此
flatMap
相当于
map
操作,然后是
flatte
操作)。您必须记住的第二件事是您正在修改(映射)嵌套列表,因此您还需要嵌套
map
/
flatMap
调用。这些例子应该向您阐明所有这些事情:

scala>val wordlist=List(List(“abc”)、List(“de”)、List(“f”)、List()
单词列表:List[List[String]=List(List(abc)、List(de)、List(f)、List())
scala>val words=wordsLists.flant
单词:列表[字符串]=列表(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”)).flant//等价物:wordsLists.flatMap(=>List(“xyz”))
replacedWords:List[String]=List(xyz,xyz,xyz,xyz)
scala>val UpperCaseWordList=wordsLists.map(0.map(0.toUpperCase))
大写单词列表:List[List[String]=List(List(ABC)、List(DE)、List(F)、List())
scala>val upperCaseWords=wordsLists.map(u.map(u.toUpperCase)).flant//等价物:wordsLists.flatMap(u.map(u.toUpperCase))
大写字母:List[String]=List(ABC、DE、F)
scala>val OptionalFirstLetterList=单词列表.map(0.map(0.headOption))
OptionalFirstLetterList:List[List[Option[Char]]=List(List(一些(a)),List(一些(d)),List(一些(f)),List())
scala>val optionalFirstLetters=wordlist.map(0.map(0.headOption)).flant//等价物:wordlist.flatMap(0.map(0.headOption))
optionalFirstLetters:List[选项[Char]]=列表(一些(a),一些(d),一些(f))
scala>val firstLetterLists=wordLists.map(u.map(u.headOption).flatte)//等价物:wordLists.map(u.flatMap(u.headOption))
firstLetterLists:List[List[Char]=List(List(a)、List(d)、List(f)、List())
scala>val firstLetters=wordLists.map(0.flatMap(0.headOption)).flant//等价物:wordLists.flatMap(0.flatMap(0.headOption))
第一个字母:List[Char]=List(a,