如何使用scala udf更改字符串的顺序
root
|-- Loc: string (nullable = true)
+----------------+
| Loc|
+----------------+
|8106f510000dc502|
+----------------+
8106f510000dc502 to 08f150000dc50261
我想按照这个顺序转换它[3,1,5,7,6,(8-16),4,2]
答案 0 :(得分:2)
出现就像Scala编码一样,几乎与Spark无关。
我会做以下事情:
// the dataset
val loc = Seq("8106f510000dc502").toDF("Loc")
// the udf for decoding loc
def mydecode(codes: Seq[Int]) = udf { s: String =>
codes.map(pos => s.charAt(pos)).mkString
}
val codes = Seq(3,1,5,7,6,4,2)
val decoded = loc.withColumn("decoded", mydecode(codes)($"loc"))
scala> decoded.show
+----------------+-------+
| Loc|decoded|
+----------------+-------+
|8106f510000dc502|61501f0|
+----------------+-------+
我将离开codes
阵列中的范围,即(8-16)
作为您的主场练习。
答案 1 :(得分:0)
如果您希望在100z200
列上从200z100
转到Loc
,那么定义udf
功能如下所示就足够了(假设您有z
}在列中每个字符串的中间)
def reverseReplace = udf((str: String) => {
val index = str.indexOf("z")
str.substring(index+1, str.length)+str.substring(index, index+1)+str.substring(0, index)
})
您可以将udf
功能称为
val m4=msc3.select("Loc").withColumn("Info", reverseReplace($"Loc"))
m4.show(false)
您将获得以下输出
+-------+-------+
|Loc |Info |
+-------+-------+
|100z200|200z100|
|30z400 |400z30 |
|600z10 |10z600 |
+-------+-------+
<强>被修改强>
根据我从您的更新问题中了解到您希望以[3,1,5,7,6,(8-16),4,2]
顺序获得最终结果的内容,以下内容可以是您的udf
函数
def reverseReplace = udf((str: String) => {
val len = str.length
val index = 16 > len match {case true => len case false => 16}
var finalStr = ""
if(len > 2)
finalStr += str.substring(3-1,3)
if(len > 0)
finalStr += str.substring(1-1,1)
if(len > 4)
finalStr += str.substring(5-1,5)
if(len > 6)
finalStr += str.substring(7-1,7)
if(len > 5)
finalStr += str.substring(6-1,6)
if(len > 7)
finalStr += str.substring(8-1, index)
if(len > 3)
finalStr += str.substring(4-1,4)
if(len > 1)
finalStr += str.substring(2-1,2)
if(finalStr == "")
finalStr = str
finalStr
})
您可以按照上述说明调用此udf
功能
答案 2 :(得分:0)
使用正则表达式和可分配分隔符的UDF的另一种方法(在本例中为&#34; z&#34;):
def flip(sep: String) = udf(
(s: String) => {
val pattern = s"""(.*?)${sep}(.*)""".r
s match {
case pattern(a, b) => b + sep + a
}
}
)
val df = Seq( ("100z200") ).toDF("Loc")
val dfFlipped = df.withColumn("Flipped", flip("z")($"Loc"))
dfFlipped.show
+-------+-------+
| Loc|Flipped|
+-------+-------+
|100z200|200z100|
+-------+-------+