Scala Spark for循环UDF处理带斜杠范围字符串生成区间数组问题
问题根因
- 原UDF定义入参为
(Int, Int)类型,当传入new1列的“44/1”值时,Spark会在入参传递阶段自动将字符串转为Int,斜杠字符导致类型解析失败,返回null值,UDF内部逻辑根本无法正常触发,这就是带斜杠行结果为null的直接原因。 - 原UDF仅实现了纯数字区间的遍历生成逻辑,未覆盖带斜杠格式范围的生成规则,即便解决类型转换问题,也无法输出符合预期的结果。
适配双场景的实现方案
逻辑调整要点
- 将UDF入参类型从
Int改为String,避免非纯数字值在传参阶段就被强制转成null。 - UDF内部做分支判断:
- 若起始值不含斜杠:走原有纯数字遍历逻辑,将字符串转为整数后生成连续区间值。
- 若起始值含斜杠:拆分出斜杠前的固定前缀、斜杠后的起始后缀数字,从起始后缀遍历到结束值的前一位,逐次拼接
前缀/后缀数字格式的字符串;最后追加固定前缀、结束值字符串,完全匹配预期的输出结构。
- UDF返回类型设为字符串数组,兼容两类场景的输出格式,整数类的区间值直接转字符串存储,展示效果和原有纯数字数组完全一致。
可直接运行的代码
导入依赖:
import scala.collection.mutable.ArrayBuffer import org.apache.spark.sql.functions.udf
定义适配的UDF:
val generateRangeArr = udf((startVal: String, endVal: String) => { val resBuffer = ArrayBuffer[String]() if (startVal.contains("/")) { // 处理带斜杠的范围格式 val Array(prefix, startSuffix) = startVal.split("/") val suffixStart = startSuffix.toInt val endNum = endVal.toInt // 生成带斜杠的区间段 for (curSuffix <- suffixStart until endNum) { resBuffer += s"$prefix/$curSuffix" } // 补充后续值匹配预期输出 resBuffer += prefix resBuffer += endVal } else { // 处理常规纯数字范围 val numStart = startVal.toInt val numEnd = endVal.toInt for (curNum <- numStart to numEnd) { resBuffer += curNum.toString } } resBuffer.toArray })
替换原有UDF调用:
r_df4.withColumn("new", generateRangeArr(col("new1"), col("new3"))).show(false)
运行输出效果
调整后输出与预期完全一致:
+---+---------+----+----+----+-------------------+ |id |range |new1|new2|new3|new | +---+---------+----+----+----+-------------------+ |1 |1 to 6 |1 |to |6 |[1, 2, 3, 4, 5, 6] | |2 |44/1 to 3|44/1|to |3 |[44/1, 44/2, 44, 3]| +---+---------+----+----+----+-------------------+
内容的提问来源于stack exchange,提问作者sunil kumar reddy
相关产品推荐
相关产品推荐

