2016-05-17 27 views
0

我想要在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, 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')

回答

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

代碼listwords flatMap (_+"1")可以重寫爲listwords flatMap (list => list.toString + "1")。所以你基本上使用toString方法將所有列表轉換爲字符串。

要獲得你可以使用下面的表達式第一字符:

listwords.flatMap(_.headOption).flatMap(_.headOption) 
+0

你不必叫'headOption'兩次: ''listwords.flatMap是 –

+0

,這也是(_ flatMap(_ headOption)。)應該工作 – maksim07

+1

您確實需要'headOption'兩次,因爲您只需要* first *字符串的第一個字符。 –

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"

0

首先,你需要理解上的差異在map和t之間他flatMap方法。它們都在一個容器上迭代,併爲每個元素應用一個函數文字。區別在於flatMap正在進行額外的操作:它將容器的結構展平。還有一種方法可以讓您只進行拼合並將其稱爲flatten(因此flatMap相當於map操作,後面是flatten操作)。你必須記住的第二件事是你正在修改(映射)嵌套列表,所以你也需要嵌套你的調用。這些例子應該澄清所有這些東西給你:

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) 
相關問題