下面的代码没有给我想要的输出。我将finallist
的输出作为单个字符并用逗号分隔;我期待的列表中只有两个值(文件名,sizeofcolumn)。
val pathurl="adl://*****.azuredatalakestore.net/<folder>/<sub_folder>"
val filelist=dbutils.fs.ls(pathurl)
val newdf = df.select("path").rdd.map(r => r(0)).collect.toList
var finallist = scala.collection.mutable.ListBuffer.empty[Any]
newdf.foreach(f => {
val MasterPq = spark.read.option("header","true").option("inferSchema","true").parquet(f.toString())
val size = MasterPq.columns.length
val mergedlist = List(f.toString(), size.toString())
mergedlist.map((x => {finallist = finallist ++ x}))
})
println(finallist)
答案 0 :(得分:2)
代码中的错误是您正在使用++
方法将值追加到列表中。此方法用于附加两个列表。
scala> List(1, 2) ++ List(3, 4)
res0: List[Int] = List(1, 2, 3, 4)
在scala中,字符串被视为一个字符列表,因此您将每个单独的字符追加到列表中。
scala> List(1, 2) ++ "Hello"
res3: List[AnyVal] = List(1, 2, H, e, l, l, o)
由于使用的是可变列表,因此可以使用'+ ='方法附加值。如果您只想使代码正常工作,那么下面的内容就足够了,但这不是一个很好的解决方案。
// mergedlist.map((x => {finallist = finallist ++ x}))
mergedlist.map((x => finallist += x}))
您可能是scala的新手,它来自Java之类的命令性语言。正如您从此类编程语言所知,Scala集合不起作用。默认情况下,Scala的集合是不可变的。无需修改集合,而是使用诸如map
之类的功能基于旧列表构建新列表。
map
函数是列表上最常用的函数之一。它采用匿名函数作为参数,该参数采用一个元素并将其转换为另一个值。此功能将应用于列表的所有方法,从而建立一个新列表。这是一个示例:
scala> val list = List(1, 2, 3).map(i => i * 2)
list: List[Int] = List(2, 4, 6)
在此示例中,将整数乘以2的函数应用于列表中的每个元素。结果将放入新列表中。也许此插图有助于理解该过程:
List(1, 2, 3)
| | |
* 2 * 2 * 2
↓ ↓ ↓
List(2, 4, 6)
我们可以使用map
函数来解决您的任务。
我们可以使用它将newdf
列表中的每个元素映射到具有相应(filename, filesize)
的元组。
val finallist = newdf.map { f =>
val masterPq = spark.read.option("header","true").option("inferSchema","true").parquet(f.toString())
val size = masterPq.columns.length
(f.toString(), size.toString())
}
我认为这段代码更短,更简单,更易于阅读,并且更漂亮。我肯定会建议您进一步了解Scala的收藏和不可变的收藏。一旦了解了它们,便会爱上它们!