Dataset[Row] 转为Array[String]

写在前面

在实际开发中,我遇到一个场景:将源数据读取进来,加载为DataFrame之后,其中一个处理步骤是,需要将某一列的数据单独提取出来作为一个数组,然后传递给后面的udf()函数。

需求:读取的是日期字段列,因为在数据仓库中,各个数据表的数据形态是不一致的,每种数据形态都有自己的日期字段,一般来说:比如,快照表我们的日期字段可能是DW_XX_DT。这个就看自己公司如何定义了。

我这里遇到的情况是:日期字段列中有空字符串""(读出来是null),还有中文字符"为空",然后还有DW_XX_DT 或 Dw_xx_Dt 这种大小写。

类似这种:把上面这个转成下面这个
在这里插入图片描述

最后得到的是:转大写 、 去重 、去空字符串 、 去"为空"字符 的一个数组。

我这里封装成了一个方法:

  def getTableFiledArray(t :DataFrame): mutable.Buffer[String] = {
    
    

    var returnTableFiledArray:mutable.Buffer[String] =  t.select("日期字段")
      .filter(!_.isNullAt(0)) // 去掉null
      .distinct() // 去掉本身重复的
      .as(Encoders.STRING).collect().toBuffer // Dataset[Row] ==> mutable.Buffer[String]

    // ================接下来就是一些Scala数组的操作================
    // delete elements from an Array or ArrayBuffer
    returnTableFiledArray -= ("为空")

    for ( i <- 0 until returnTableFiledArray.length){
    
    
      // 转大写
      returnTableFiledArray(i) = returnTableFiledArray(i).toUpperCase()
    }

    returnTableFiledArray.distinct

  }

直接调用:

    inputDF.show()
    
    val tableFiledArray =  getTableFiledArray(inputDF.select("日期字段"))

    for (tableFiled <- tableFiledArray){
    
    
      println(tableFiled)
    }

得到如下结果:
在这里插入图片描述
后面我就可以把 tableFiledArray 传递给udf()函数了。

参考:
https://hello-scala.com/201-scala-arraybuffer-examples.html
https://alvinalexander.com/scala/how-to-delete-array-arraybuffer-elements-scala-cookbook/

-------------扩展-------------

  def apply[T: ClassTag](xs: T*): Array[T] = {
    
    
    val array = new Array[T](xs.length)
    var i = 0
    for (x <- xs.iterator) {
    
     array(i) = x; i += 1 }
    array
  }

猜你喜欢

转载自blog.csdn.net/liuge36/article/details/107026322
Row