在普通 Scala 中是否有等效的爆炸函数?

Met*_*ata 1 scala

我正在尝试在普通的 Scala 而不是 Spark 中寻找爆炸函数或其等效函数。使用 Spark 中的爆炸功能,我能够将具有多个元素的一行平展为多行,如下所示。

scala> import org.apache.spark.sql.functions.explode
import org.apache.spark.sql.functions.explode

scala> val test = spark.read.json(spark.sparkContext.parallelize(Seq("""{"a":1,"b":[2,3]}""")))

scala> test.schema
res1: org.apache.spark.sql.types.StructType = StructType(StructField(a,LongType,true), StructField(b,ArrayType(LongType,true),true))

scala> test.show
+---+------+
|  a|     b|
+---+------+
|  1|[2, 3]|
+---+------+

scala> val flat = test.withColumn("b",explode($"b"))
flat: org.apache.spark.sql.DataFrame = [a: bigint, b: bigint]

scala> flat.show
+---+---+
|  a|  b|
+---+---+
|  1|  2|
|  1|  3|
+---+---+
Run Code Online (Sandbox Code Playgroud)

在不使用 Spark 的情况下,普通 scala 中是否有爆炸等效函数?如果 Scala 中没有可用的爆炸功能,我是否可以实现它?

Iva*_*nko 6

flatMap在这种情况下,简单应该可以帮助您。我不知道您想在 Scala 中使用的确切数据结构,但让我们举一个有点人为的例子:

val l: List[(Int, List[Int])] = List(1 -> List(2, 3))
val result: List[(Int, Int)] = l.flatMap {
  case (a, b) => b.map(i => a -> i)
}
println(result)
Run Code Online (Sandbox Code Playgroud)

这将产生下一个结果:

List((1,2), (1,3))
Run Code Online (Sandbox Code Playgroud)

更新

正如@jwvh 在评论部分所建议的那样,或者使用for-comprehension构造和隐藏显式flatMap&map调用可以获得相同的结果:

val result2: List[(Int, Int)] = for((a, bList) <- l; b <- bList) yield a -> b
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!

  • `flatMap()` 内有一个 `map()`?这就是我们的朋友“for”理解的目的:“for {(k, ls) &lt;- l; v &lt;- ls} 产量 (k,v)` (3认同)