1. 序章

機能コンビネーターmap ()および flatMap()は、Apache SparkRDD、DataFrame、およびDataSetにある高階関数です。 。 これらのコレクションを使用すると、コレクション内のすべての要素に対して変換を実行し、結果を含む新しいコレクションを返すことができます。

Sparkのmap()および flatMap()関数は、Scalaプログラミング言語で同等のものをモデルにしているため、この記事で学習する内容はそれらにも適用できます。

map() flatMap()の違いを理解するのに役立ついくつかの例を見てみましょう。

2. map()の例

map()メソッドは、コレクションの各要素に関数を適用することにより、コレクションを変換します。 次に、結果を含む新しいコレクションを返します。

次のspark-shellの例では、 map()を使用して、コレクション内の各文字列を空の文字列で分割します。

val rdd = sc.parallelize(Seq("map vs flatMap", "apache spark"))
rdd.map(_.split(" ")).collect

res1: Array[String] = Array(Array("map", "vs", "flatMap"), Array("apache", "spark"))

ご覧のとおり、 map()メソッドは、関数 split( “”)をパラメーターとして受け取り、RDDのすべての要素に適用します。 変換の結果は、新しいコレクションとして返されます。 元の要素と同様に2つの要素が含まれていますが、要素の内容は、最初の要素の内容に対して split( “”)を実行した結果です。

したがって、 map()は長さNのコレクションを長さNの別のコレクションに変換すると結論付けることができます。

3. flatMap()の例

flatMap()は、mappingflatteningを組み合わせたものです。 最初にmap()メソッドを実行し、次に flatten()メソッドを実行して結果を生成します。 flatten メソッドは、コレクションの要素を折りたたんで、同じタイプの要素を持つ単一のコレクションを作成します。

同じ例を見て、代わりに flat Map()をコレクションに適用してみましょう。

val rdd = sc.parallelize(Seq("map vs flatMap", "apache spark"))
rdd.flatMap(_.split(" ")).collect

res1: Array[String] = Array("map", "vs", "flatMap", "apache", "spark")

結果は、前の例の出力からの2つのネストされたコレクションのすべての要素を含むコレクションです。

これがどのように機能するかを理解するために、 map()メソッドを呼び出した後の前の例の出力をもう一度見てみましょう。

res1: Array[String] = Array(Array("map", "vs", "flatMap"), Array("apache", "spark"))

flatMap()は、この出力に対して flatten()を実行し、ネストされたコレクションを含まず、代わりにネストされたコレクションの各要素を含む新しい結果を生成します。

flatMap ()を使用するもう1つの便利な方法は、タイプOptionのコレクションを処理する場合です。 出力をフラット化すると、値を持つすべての要素をすばやく取得できます。

val mapOutput = strings.map(toInt)
mapOutput: Seq[Option[Int]] = List(Some(3), Some(5), None, Some(8), None, None, Some(12))

val flattenOutput = mapOutput.flatten
flattenOutput: Seq[Int] = List(3, 5, 8, 12)

4. 結論

結論として、 map()が長さNのコレクションを別の長さNのコレクションに変換する方法を確認できます。

flatMap()は、出力で flatten()を実行する前に、 map()と同じ初期変換を実行します– flatten()は、アイテムとシーケンスを生成します。