Scala:如何在循环块外的for循环中使用变量

Scala : How to use variable in for loop outside loop block

当读取每个文件后我需要将文件名添加为数据帧中的字段时,如何使用我的所有 json 文件创建数据帧? for 循环中的变量似乎在循环外无法识别。如何克服这个问题?

for (jsonfilenames <- fileArray) {
      var df = hivecontext.read.json(jsonfilename)
      var tblLanding = df.withColumn("source_file_name", lit(jsonfilename))

    }

   // trying to create temp table from dataframe created in loop

tblLanding.registerTempTable("LandingTable") // ERROR here, can't resolved tblLanding

提前致谢
侯赛因

我认为您是编程本身的新手。 不管怎样,你走了。

基本上你指定类型并在循环之前初始化它。

var df:DataFrame = null
for (jsonfilename <- fileArray) {
      df = hivecontext.read.json(jsonfilename)
      var tblLanding = df.withColumn("source_file_name", lit(jsonfilename))

    }

df.registerTempTable("LandingTable") // Getting ERROR here

更新

好的,您是编程新手,甚至是循环。

假设 fileArray 的值为 [1.json、2.json、3.json、4.json]

因此,循环实际上通过读取 4 个 json 文件创建了 4 个数据帧。 您要将哪一个注册为临时 table.

如果全部,

var df:DataFrame = null
var count = 0
for (jsonfilename <- fileArray) {
      df = hivecontext.read.json(jsonfilename)
      var tblLanding = df.withColumn("source_file_name", lit(jsonfilename))
      df.registerTempTable(s"LandingTable_$count")
      count++;
    }

在此更新之前 df 为空的原因是,您的 fileArray 为空或 Spark 无法读取该文件。打印出来检查一下。

查询任何已注册的LandingTable

val df2 = hiveContext.sql("SELECT * FROM LandingTable_0")

更新 问题已更改为从所有 json 文件制作单个数据帧。

var dataFrame:DataFrame = null
for (jsonfilename <- fileArray) {
   val eachDataFrame = hivecontext.read.json(jsonfilename)
   if(dataFrame == null)
      dataFrame = eachDataFrame
   else
      dataFrame = eachDataFrame.unionAll(dataFrame)
}
dataFrame.registerTempTable("LandingTable")

确保 fileArray 不为空,并且 fileArray 中的所有 json 个文件都具有相同的架构。

// Create list of dataframes with source-file-names
val dfList = fileArray.map{ filename =>
  hivecontext.read.json(filename)
             .withColumn("source_file_name", lit(filename))
}

// union the dataframes (assuming all are same schema)
val df = dfList.reduce(_ unionAll _)  // or use union if spark 2.x

// register as table
df.registerTempTable("LandingTable")