2017-08-25 20 views
2

Scalaは配列番号は次のように動作する機能を存在している存在します同様に。私たちは、次のsourceDFがあるとします。スパークを作成存在するユーザー定義関数は、関数

+---------+ 
|  nums| 
+---------+ 
|[1, 4, 9]| 
|[1, 3, 5]| 
+---------+ 

私はこのような何かを書くことができるようにしたいと思います:

def existsInt(arr: Array[Int], f: (Int => Boolean)): Boolean = { 
    arr.exists(f(_)) 
} 

val exists = udf[Boolean, Array[Int], (Int => Boolean)](existsInt) 

私は理由を理解:

val actualDF = sourceDF.withColumn(
    "nums_has_even", 
    exists(col("nums"), (x: Int) => x % 2 == 0) 
) 

ここで私が書いたコードです私のコードは動作していません。 UDFは列引き数を必要とし、無名関数は列オブジェクトではありません。​​3210に匿名関数をラップすると、動作しませんでした:

exists(col("nums"), lit((x: Int) => x % 2 == 0)) // doesn't work 

は、どのように私はこのコードが動作して入手できますか?

答えて

2

あなたはかなり接近している:

def existsInt(f: (Int => Boolean)) = udf { 
    (arr: Seq[Int]) => arr.exists(f(_)) // Not Array! 
} 

使用法:

existsInt((x: Int) => x % 2 == 0)(col("nums")) 

あなたも、次のことができます。

scala.reflect.runtime.universe._ 

def exists[T : TypeTag](f: (T => Boolean)) = udf[Boolean, Seq[T]]{ 
    (arr: Seq[T]) => arr.exists(f(_)) // Not Array! 
} 

exists[Int]((x: Int) => x % 2 == 0).apply(col("nums")) 
関連する問題