Вы можете достичь этого без UDF. Давайте создадим ваш фрейм данных:
val df = Seq(Seq(Map("a" -> "a1", "b" -> "b1"), Map("c" -> "c1", "d" -> "d1"))).toDF()
df.show(false)
df.printSchema()
output:
+----------------------------------------+
|value |
+----------------------------------------+
|[[a -> a1, b -> b1], [c -> c1, d -> d1]]|
+----------------------------------------+
root
|-- value: array (nullable = true)
| |-- element: map (containsNull = true)
| | |-- key: string
| | |-- value: string (valueContainsNull = true)
Если ваш массив содержит 2 элемента, просто используйте map_concat
:
df.select(map_concat('value.getItem(0), 'value.getItem(1))).show(false)
или этот (I понятия не имею, как динамически l oop из 0 в 'значение размера столбца типа массива, это может быть самое короткое решение)
df.select(map_concat((for {i <- 0 to 1} yield 'value.getItem(i)): _*)).show(false)
В противном случае, если ваш массив содержит несколько карт и размеров неизвестно, вы можете попробовать следующий метод:
val df2 = df.map(s => {
val list = s.getList[Map[String, String]](0)
var map = Map[String, String]()
for (i <- 0 to list.size() - 1) {
map = map ++ list.get(i)
}
map
})
df2.show(false)
df2.printSchema()
вывод:
+------------------------------------+
|value |
+------------------------------------+
|[a -> a1, b -> b1, c -> c1, d -> d1]|
+------------------------------------+
root
|-- value: map (nullable = true)
| |-- key: string
| |-- value: string (valueContainsNull = true)