我正在尝试将sparkDataframe的某些列中的值作为键存储在scala.immutable.map[x,double]中,并尝试决定将哪个容器类型x用作键。
列的数量和每列的数据类型在编译时是未知的,这取决于用户的输入(因为用户提供了要用作Map键的列列表以及正在读取的Dataframe)。
哪个容器类型适合用作此Map的键?
我曾想过使用元组作为键,但由于我不知道编译时的列数及其数据类型,因此无法创建元组。
我尝试使用use a row作为Map键,但这会导致key not found错误,即使用于查找的行与Map中的某些行具有相同的值和架构。使用一行是一个黑客,我只是选择尝试这一点,因为我想不出还有什么可以使用。
val df = spark.read.json("....") // shall be user input
val keyColumns = Array[String]("number", "word") // shall be user input
val dfAsMap = df.select(struct(keyColumns.head, keyColumns.tail: _*).as("structCol"), struct($"*").as("originalData"))
.rdd
.map(row => (row.getAs[Row]("structCol"), row.getAs[Row]("originalData")))
.collect()
.toMap
println(dfAsMap) // prints Map([8,bat] -> [8,blahblah,bat], ...)
println(dfAsMap(dfAsMap.head._1)) // successful lookup, no surprise
println(dfAsMap(df.select(struct("number", "word").as("structCol")).take(1).head)) // key not found
val schema = df.select("number", "word").schema
val row1: Row = new GenericRowWithSchema(Array("8", "bat"), schema)
println(dfAsMap(row1)) // key not found
我创建的以下poc有效,使我相信行可以用作Map键,直到它不起作用:https://pastebin.com/mpmvuem7
我也尝试过使用数组,但没有成功-它只在引用与Map中相同的数组对象时有效。
val array = Array[String]("a", "b")
val mymap = Map(array -> "blue", Array[String]("c", "d") -> "red")
println(mymap(array)) // gives blue
println(mymap(Array("a", "b"))) // key not found exception
因此,问题陈述变成了:考虑到在运行时之前不知道组成键的元素的数量和数据类型这一难题,我可以使用什么容器/集合类型在Map中存储键?
暂无答案!
目前还没有任何答案,快来回答吧!