如何在Scala中向数组添加元素并查找变量类型?

时间:2018-12-16 21:06:00

标签: scala apache-spark apache-spark-sql user-defined-functions

我将下面的Scala代码块作为数据处理管道的一部分。根据到目前为止的理解,UDF接受一个file_contents类型的参数String。然后,UDF进行一堆字符串处理,包括split

该代码可以正常工作,但是我试图以下列方式进行编辑并且很挣扎,这主要是由于我对Scala的经验不足以及难以在线找到答案。

  • 我希望能够根据info的长度为info提供2个空字符串和2个零。如果info的长度为28,则将这四个值相加,否则继续。如何在下面的代码中完成此操作?我想在val param_data之前添加此代码。

如果有人不介意回答,我还会对此代码提出以下问题。

  1. 如果split将字符串转换为数组,为什么我不能使用println(info)打印字符串的长度?相反,这行似乎打印了很大的数字,我相信这是所有字符串的总长度。
  2. 您如何知道此UDF返回什么?我没有看到像Python等中的return语句。

    def extract_FileContent_test = udf((file_contents: String) => {
    
       val info = (file_contents.replace("\",\"", "     ")
        .replace("\"", "")
        .replaceAll("    ", "|")
        .replaceAll(" : \r\n", " : empty\r\n")
        .replaceAll("\r\n", "|")
        .replaceAll(" : ", "|")
        .replaceAll(": ", "|")
        .split("\\|")
        .map(x => x.trim.replaceAll(" -", ""))
        .filterNot(s => s == ""))
       println(info.length)
       // type info : Array[String]
    
       // type sec_index : Array[Int]
       val sec_index = info.zipWithIndex.filter(_._1.startsWith("---")).map(_._2)
    
       if (sec_index.length > 2) {
    
       // parse meta_data (beam tuning context) and param_data (beam tuning parameter) separately
    
       val meta_data = (info.slice(0, sec_index(0)).toList.grouped(2)
        .filter(l => l.length == 2)
        .filter(l => l(1) != "Start" & l(1) != "")
        .map { case List(a, b) => b }
        .toArray.mkString(",")
        )
    
       // println(meta_data)
    
       val param_data = (info.slice(sec_index(0) + 1, sec_index(1)).toList.grouped(3)
        .filter(l => l.length == 3)
        .filter { case List(a, b, c) => Try(c.split(" ")(0).toDouble).isSuccess }
        .map { case List(a, b, c) => Array(a, c.split(" ")(0)).mkString(",") }
        .toArray)
       // println(param_data)
    
       /* one meta data will have > 100 param
       so besides meta columns, we add 2 columns for param_name, param_value
       */
       param_data.map(meta_data + "," + _)
       }
       else {
       Array[String]()
       }
       })
    

1 个答案:

答案 0 :(得分:0)

  1. 要获取信息的长度,请使用info.length
  2. 在Scala中,最后一条语句是返回值-这里是if (sec_index.length > 2),因此它要么返回一个空字符串数组,要么在最后一个映射之后返回params_data

关于向信息添加数据,您可以执行以下操作

val info_with_filler =  if ( info.length<28) info ++  List("","" ,"0","0") else info

,然后在代码中稍后使用info_with_filler代替info