我對 scala 和 udf 很陌生,現在我想撰寫一個 udf,它接受來自資料框列的 3 個引數(其中一個是陣列),for..loop 當前陣列,決議并回傳將使用的案例類然后。這是我的代碼大致:
case class NewFeatures(dd: Boolean, zz: String)
val resultUdf = udf((arrays: Option[Row], jsonData: String, placement: Int) => {
for (item <- arrays) {
val aa = item.getAs[Long]("aa")
val bb = item.getAs[Long]("bb")
breakable {
if (aa <= 0 || bb <= 0) break
}
val cc = item.getAs[Long]("cc")
val dd = cc > 0
val jsonData = item.getAs[String]("json_data")
val jsonDataObject = JSON.parseFull(jsonData).asInstanceOf[Map[String, Any]]
var zz = jsonDataObject.getOrElse("zz", "").toString
NewFeatures(dd, zz)
}
})
當我運行它時,它會得到例外:
java.lang.UnsupportedOperationException: Schema for type Unit is not supported
我應該如何修改上面的udf
uj5u.com熱心網友回復:
首先,嘗試更好地命名您的變數,例如在您的情況下,“陣列”的型別為Option[Row]. 在這里,for (item <- arrays) {...}基本上是一種.map方法,在選項上使用 map,您應該提供一個函式,該函式使用 Row 并回傳某種型別的值(~= 簽名:def map[V](f: Row => V): Option[V],您想要的情況:)def map(f: Row => NewFeatures): Option[NewFeature]。當您在某些情況下打破此映射時,編譯器無法保證 map 方法中的函式將始終回傳 NewFeatures 的實體。所以它是 Unit(它只在某些情況下回傳,而不是全部)。您想要做的事情可以通過類似的方式得到增強:
val funcName: (Option[Row], String, Int) => Option[NewFeatures] =
(rowOpt, jsonData, placement) => rowOpt.filter(
/* your break condition */
).map { row => // if passes the filter predicate =>
// fetch data from row, create new instance
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/459752.html
上一篇:從存盤的角度來看,Scala如何在內部表示不可變映射?
下一篇:Scala:遞回和堆疊溢位錯誤
