Scala 如何将spark sql udf作为函数实现?
我需要实现一个Scala 如何将spark sql udf作为函数实现?,scala,apache-spark,Scala,Apache Spark,我需要实现一个spark.sql.functions.udf来进行一些复杂的过滤 我有一些例子,但大多数都很简单,都是作为闭包实现的。虽然在闭包中控制返回值并不简单 这是一个exmaple: val filterClosure: UserDefinedFunction = udf { (ips: mutable.WrappedArray[String]) => for (ip <- ips) { if (!(ip.startsWith("abc") || ip.start
spark.sql.functions.udf
来进行一些复杂的过滤
我有一些例子,但大多数都很简单,都是作为闭包实现的。虽然在闭包中控制返回值并不简单
这是一个exmaple:
val filterClosure: UserDefinedFunction = udf {
(ips: mutable.WrappedArray[String]) =>
for (ip <- ips) {
if (!(ip.startsWith("abc") || ip.startsWith("def"))) true
}
false
}
val ds = Seq((0, Array("hello", "baby", "word")), (1, Array("abcgod", "deftest"))).toDF("id", "words")
ds.filter(filterClosure($"words")).show()
那么,如何将其实现为函数呢?使用
udf
包装定义的函数:
def filterFunction(words: mutable.WrappedArray[String]): Boolean = {
for (wd <- words) {
if (!(wd.startsWith("abc") || wd.startsWith("def"))) return true
}
false
}
val filterUdf = udf(filterFunction _)
ds.filter(filterUdf($"words")).show()
代码的问题在于匿名函数:它总是返回false,因为
false
是最后一条语句。所以你的循环什么都不做。您使用循环中的函数literalfilterFunction
和return
解决了这个问题。但是不建议在Scala中使用return
,并且有很多方法可以与集合交互。那么为什么不直接使用exists
方法呢
val ds = Seq((0, Array("hello", "baby", "word")), (1, Array("abcgod", "deftest"))).toDF("id", "words")
val filterClosure = udf {
(ips: scala.collection.mutable.WrappedArray[String]) => ips.exists(ip => !(ip.startsWith("abc") || ip.startsWith("def")))
}
ds.filter(filterClosure($"words")).show()
+---+-------------------+
| id| words|
+---+-------------------+
| 0|[hello, baby, word]|
+---+-------------------+
这就是结果
强烈建议不要编写自己的方法,而不要编写Scala Collections API中包含的方法。@Dimitry谢谢您的建议。@secfree欢迎您:)--JetBrains上IntelliJ Scala插件开发人员提供的有用文章。这很有帮助。
+---+-------------------+
| id| words|
+---+-------------------+
| 0|[hello, baby, word]|
+---+-------------------+
val ds = Seq((0, Array("hello", "baby", "word")), (1, Array("abcgod", "deftest"))).toDF("id", "words")
val filterClosure = udf {
(ips: scala.collection.mutable.WrappedArray[String]) => ips.exists(ip => !(ip.startsWith("abc") || ip.startsWith("def")))
}
ds.filter(filterClosure($"words")).show()
+---+-------------------+
| id| words|
+---+-------------------+
| 0|[hello, baby, word]|
+---+-------------------+