Попробуйте это -
Используйте scala.collection.mutable.WrappedArray
и преобразуйте его в список java, используя JavaConverters
, затем отсортируйте его с помощью компаратора и выберите первую самую короткую строку -
Dataset<Row> df = spark.sql("select array('abc', 'ab', 'a') arr");
df.printSchema();
df.show(false);
/**
* root
* |-- arr: array (nullable = false)
* | |-- element: string (containsNull = false)
*
* +------------+
* |arr |
* +------------+
* |[abc, ab, a]|
* +------------+
*/
// scala.collection.mutable.WrappedArray
UserDefinedFunction shortestStringUdf = udf((WrappedArray<String> arr) -> {
List<String> strings = new ArrayList<>(JavaConverters
.asJavaCollectionConverter(arr)
.asJavaCollection());
strings.sort(Comparator.comparing(String::length));
return strings.get(0);
}
, DataTypes.StringType);
spark.udf().register("shortestString", shortestStringUdf);
df.withColumn("a", expr("shortestString(arr)"))
.show(false);
/**
* +------------+---+
* |arr |a |
* +------------+---+
* |[abc, ab, a]|a |
* +------------+---+
*/
Если вы используете spark>=2.4
, используйте функции высшего порядка для достижения того же результата without udf
, как показано ниже -
// spark>=2.4
df.withColumn("arr_length", expr("TRANSFORM(arr, x -> length(x))"))
.withColumn("a", expr("array_sort(arrays_zip(arr_length, arr))[0].arr"))
.show(false);
/**
* +------------+----------+---+
* |arr |arr_length|a |
* +------------+----------+---+
* |[abc, ab, a]|[3, 2, 1] |a |
* +------------+----------+---+
*/