2016-05-17 2 views
0

私はflatMapの実装をScalaで実装しようとしています。 Scalaプログラミングの定義に基づいてscalaでのFlatMapの動作

要素を右の引数として返す関数です。関数を各リストに適用し、すべての関数結果の連結を返します。

今、これを理解するために、私は次のようしている実装なぜList[List[String]]List[String]のように扱われ、私は狂った駆動する第1の出力を見てみると

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[Char]にする必要があります。だからlistwordsが与えられたら、出力はList('a', 'd', 'g')になります。

答えて

1

List("abc").toString + "1"に相当し、文字列 "List(a、b、c)1"を返します。 List.flatMapのタイプは

flatMap[B](f: (A) ⇒ GenTraversableOnce[B]): List[B] 

とあなたの関数である(List[String] => String)を入力しています。 StringGenTraversableOnce[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

あなたは* first *文字列の最初の文字だけを必要とするので、 'headOption'が2回必要です。 –

0

_+"1"は、あなたがそれをやっていると思う何をしていません。 List[String]は、このような方法を含んでいないので、それはlist: List[String] => list.+("1")

として解釈されます

、コンパイラがスコープで暗黙の変換を探します。それはany2stringaddを見つける。

implicit final class any2stringadd[A](private val self: A) extends AnyVal { 
    def +(other: String): String = String.valueOf(self) + other 
} 

list: List[String] => list.+("1")

今、すべてのString.valueOf(list) + "1"

0

ファーストを返し

list: List[String] => new any2stringadd(list).+("1")

になり、あなたは違いを理解する必要があります(暗黙的な変換の詳細についてhttp://docs.scala-lang.org/tutorials/tour/implicit-conversionsを参照してください) mapとtの間彼はflatMapメソッド。どちらもコンテナを繰り返し処理し、すべての要素に関数リテラルを適用します。違いは、flatMapがもう1つの追加操作を行っていることです。コンテナの構造を平坦化します。また、平滑化とそれをflattenと呼ぶ方法もあります(flatMapmap操作の後に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) 
関連する問題