I have two similar columns of json in a dataframe:
Column A's values look like this:
{"categoryCode": "ZZ","yesNoCode": "Y","conditionIndicator1": "ST"}
Column B's values look like this:
{"categoryCode": "ZZ","yesNoCode": "Y","conditionIndicator1": "ST", "conditionIndicator2": "RN"}
I have other columns as well, whose values are similar, but have 3 condition indicators, 4 condition indicators or 5 condition indicators. Each column's values always have the same number of condition indicators.
I'd like to do something easy like val resultDf = df.select(array($"col1", $"col2", ...)) but this fails because the array function won't allow you to select columns of different types. So I need to call some function f to do a transformation on each column's json, so that all of them have five condition indicators.
val resultDf = df.select(array(f($"col1"), f($"col2"), ...)).alias("normalizedData")
This would yield:
[
{"categoryCode": "ZZ", "yesNoCode": "Y", "conditionIndicator1": "ST", "conditionIndicator2": "", "conditionIndicator3": "", "conditionIndicator4": "", "conditionIndicator5": ""},
{"categoryCode": "KF", "yesNoCode": "Y", "conditionIndicator1": "ST", "conditionIndicator2": "RN", "conditionIndicator3": "", "conditionIndicator4": "", "conditionIndicator5": ""},
{"categoryCode": "64", "yesNoCode": "N", "conditionIndicator1": "2M", "conditionIndicator2": "7X", "conditionIndicator3": "34", "conditionIndicator4": "22", "conditionIndicator5": "AE"}
]
So far what I am using is a udf, but it seems like this is the Really Hard Way, worse than string manipulation!
val createCondition = udf {(theCondition: Row) =>
if (theCondition != null) {
var m = Map(
"categoryCode" -> theCondition.getAs[String]("categoryCode"),
"yesNoCode" -> theCondition.getAs[String]("yesNoCode"),
"conditionIndicator1" -> theCondition.getAs[String]("conditionIndicator1")
)
var c2 = theCondition.getAs[String]("conditionIndicator2")
if (c2 == null) {
c2 = ""
}
m = m + ("conditionIndicator2", c2)
var c3 = theCondition.getAs[String]("conditionIndicator3")
if (c3 == null) {
c3 = ""
}
m = m + ("conditionIndicator3", c3)
// et cetera...and way worse if we had a more complex object graph...which I do!
// then return my map, m.
m
} else {
null
}
}
val result = df.select(array(createCondition($"col1"), createCondition($"col2")))
Seems like transformation of complex data is why we have databricks, so I'm certain I am doing this wrong. Should be a way have a function maps objects of type x into type y.