2017-08-25 2 views
2

Scala hat ein Array # Funktion existiert, die wie folgt funktioniert:Erstellen einer Funken existiert benutzerdefinierte Funktion, die wie die Scala Array # funktioniert existiert Funktion

Array(1, 2, 5).exists(_ % 2 == 0) // true 

Ich möchte einen Funken erzeugen Funktion besteht das funktioniert ähnlich. Angenommen, wir haben die folgende sourceDF:

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

Ich möchte in der Lage sein, so etwas zu schreiben:

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

Hier ist der Code, den ich schrieb:

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

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

Ich verstehe, warum Mein Code funktioniert nicht. UDFs erfordern Spaltenargumente und eine anonyme Funktion ist kein Column-Objekt. Umwickeln der anonyme Funktion in lit nicht funktioniert:

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

Wie kann ich diesen Code erhalten zu arbeiten?

Antwort

2

Sie sind ziemlich nah dran:

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

Verbrauch:

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

Sie können sogar:

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")) 
Verwandte Themen