Вот один из подходов, использующий UDF, который отображает каждый элемент столбца с типом массива для включения также индекса элемента:
import org.apache.spark.sql.Row
import org.apache.spark.sql.functions._
import spark.implicits._
case class Name(given_name: String, surname: String)
case class NameIdx(given_name: String, surname: String, index: Int)
val df = Seq(
Seq(Name("John", "Doe"), Name("Jane", "Smith"), Name("Mike", "Davis")),
Seq(Name("Rachel", "Smith"), Name("Steve", "Thompson"))
).toDF("name")
val addIndex = udf((names: Seq[Row]) => names.map{
case name @ Row(gn: String, sn: String) => NameIdx(gn, sn, names.indexOf(name) + 1)
})
df.select(addIndex($"name").as("name")).show(false)
// +----------------------------------------------+
// |name |
// +----------------------------------------------+
// |[[John,Doe,1], [Jane,Smith,2], [Mike,Davis,3]]|
// |[[Rachel,Smith,1], [Steve,Thompson,2]] |
// +----------------------------------------------+
Чтобы получить значения JSON, примените to_json
следующим образом:
df.select(to_json(addIndex($"name")).as("name")).show(false)
// +-----------------------------------------------------------------------------------------------------------------------------------------------------+
// |name |
// +-----------------------------------------------------------------------------------------------------------------------------------------------------+
// |[{"given_name":"John","surname":"Doe","index":1},{"given_name":"Jane","surname":"Smith","index":2},{"given_name":"Mike","surname":"Davis","index":3}]|
// |[{"given_name":"Rachel","surname":"Smith","index":1},{"given_name":"Steve","surname":"Thompson","index":2}] |
// +-----------------------------------------------------------------------------------------------------------------------------------------------------+