Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 如何将spark sql udf作为函数实现?_Scala_Apache Spark - Fatal编程技术网

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
是最后一条语句。所以你的循环什么都不做。您使用循环中的函数literal
filterFunction
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]|
+---+-------------------+