Как добавить элементы в массив в Scala и найти тип переменной? - PullRequest
0 голосов
/ 17 декабря 2018

У меня есть следующий блок кода Scala как часть моего конвейера обработки данных.Насколько я понимаю, UDF принимает один аргумент file_contents типа String.Затем UDF выполняет обработку строк, включая split.

Код работает без каких-либо ошибок, но я пытаюсь редактировать следующим образом и изо всех сил, в основном из-за моей неопытности в Scala и трудности с поиском ответов в Интернете.

  • Я хочу иметь возможность 2 пустых строк и 2 нуля до info в зависимости от длины info.Если длина info равна 28, добавьте эти четыре значения, иначе продолжите.Как я могу сделать это в приведенном ниже коде?Я хочу добавить этот код до val param_data.

У меня также есть следующие вопросы об этом коде, если кто-то не против ответить.

  1. Если split преобразует строку в массив, почему я не могу напечатать ее длину, используя println(info)?Вместо этого эта строка, кажется, печатает очень большое число, которое, я считаю, является суммарной длиной всех строк.
  2. Откуда вы знаете, что возвращается этим UDF?Я не вижу оператор return, как в Python и т. Д.

    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 голосов
/ 17 декабря 2018
  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

...