[英]How to split a List to be added to a Map in Scala with Different Data Types
I have some raw test data that I need to split into a map of format:我有一些原始测试数据需要拆分为 map 格式:
Map[String, List[(Int, String, Float)]]地图[字符串,列表[(整数,字符串,浮点数)]]
I have managed to read in the data as a list and will give an example of one line of data below:我已经设法以列表的形式读取数据,并将在下面给出一行数据的示例:
Oor Wullie Route (GCU),1:City Chambers:0.75f,2:Sir Chris Hoy Velodrome:3.8f,3:People's Palace:2.7f,4:Riverside Museum:5.4f,5:Botanic Gardens:2.4f,6:GCU:3.4f
The above represents the following: A Route, a stage number:stage name:total distance of stage以上代表如下:A Route, a stage number:stage name:total distance of stage
So each set of 3 values (ie 1:City Chambers:5) should be added to the [Int, String, Float] section of the map, with the route name being the key.因此,每组 3 个值(即 1:City Chambers:5)应添加到 map 的 [Int, String, Float] 部分,路线名称是关键。
This is my code so far for reading the file and adding it to a list:到目前为止,这是我用于读取文件并将其添加到列表中的代码:
var mapBuffer: Map[String, List[(Int, String, Float)]] = Map()
val fitnessData = "C:\\Users\\josep\\Desktop\\Coursework\\Coursework\\src\\cw.txt"
val lines = Source.fromFile("C:\\Users\\josep\\Desktop\\Coursework\\Coursework\\src\\cw.txt").getLines.toList
I would like to write a funciton for splitting the data up and adding it to a map, essentially doing this:我想编写一个函数来拆分数据并将其添加到 map,基本上是这样做的:
var key ="Oor Wullie Route (GCU)"
var newList = List((1,"City Chambers",0.75f),(2,"Sir Chris Hoy Velodrome",3.8f),(3,"People's Palace",2.7f),(4,"Riverside Museum",5.4f),(5,"Botanic Gardens",2.4f),(6,"GCU",3.4f))
mapBuffer = mapBuffer ++ Map(key -> newList)
How can I add the data to a map in my desired format?如何以我想要的格式将数据添加到 map?
My suggestion would be to use foldLeft.我的建议是使用 foldLeft。 Something like:
就像是:
val resource = Source.fromFile("src/lines.txt")
val lines = resource.getLines.toList
resource.close()
val map = lines.foldLeft(Map[String, List[(Int, String, Float)]]())((map, line) => {
val keyValuesArray = line.split(",").toList
val key = keyValuesArray.head
val listOfValuesAsString = keyValuesArray.tail
val listOfValues = listOfValuesAsString.map {
case s"$integer:$string:$float" => (integer.toInt, string, float.toFloat)
}
map + (key -> listOfValues)
})
Start with empty map, and add key->values for each line.从空的 map 开始,为每一行添加 key->values。 Also, try match expressions when you parse data in list (listOfValues part is doing that).
此外,在解析列表中的数据时尝试匹配表达式(listOfValues 部分正在这样做)。
This approach is with pattern matching
and tail recursion
.这种方法是使用
pattern matching
和tail recursion
。 I think it works very well.我认为它工作得很好。
First I convert the file into a List[Array[String]]
.首先,我将文件转换为
List[Array[String]]
。
Second I call loop to go through the list in a recursive way and build the map.其次,我以递归方式通过列表调用 go 循环并构建 map。
Third inside the loop function I call make List to build the list of tuples in a recursive way.循环内的第三个 function 我调用 make List 以递归方式构建元组列表。
As an example:举个例子:
input输入
Oor Wullie Route (GCU),1:City Chambers:0.75f,2:Sir Chris Hoy Velodrome:3.8f,3:People's Palace:2.7f,4:Riverside Museum:5.4f,5:Botanic Gardens:2.4f,6:GCU:3.4f
Oor Wullie Route2 (GCU),1:City Chambers:0.75f,2:Sir Chris Hoy Velodrome:3.8f,3:People's Palace:2.7f,4:Riverside Museum:5.4f,5:Botanic Gardens:2.4f,6:GCU:3.4f
Oor Wullie Route3 (GCU),1:City Chambers:0.75f,2:Sir Chris Hoy Velodrome:3.8f,3:People's Palace:2.7f,4:Riverside Museum:5.4f,5:Botanic Gardens:2.4f,6:GCU:3.4f
code代码
import scala.io.Source
object ConverToMap {
@annotation.tailrec
def makeList(lst: List[String], acc: List[(Int, String, Float)]):List[(Int, String, Float)] = {
lst match {
case Nil => acc
case (h :: t) => {
val data = h.split(":")
val tuple = (data(0).toInt, data(1), data(2).substring(0,data(2).length - 1 ).toFloat)
makeList(t, tuple :: acc)
}
}
}
@annotation.tailrec
def loop(lst: List[Array[String]], acc: Map[String, List[(Int, String, Float)]]): Map[String, List[(Int, String, Float)]] = {
lst match {
case Nil => acc
case (h :: t) => {
val key = h(0)
val lTuple = makeList(h.toList.tail, List())
if(acc.contains(key)) loop(t, acc)
else loop(t, Map(key -> lTuple) ++ acc)
}
}
}
def main(args: Array[String]): Unit = {
val fitnessData = "/home/cloudera/files/tests/to_map.csv"
val lines = Source.fromFile(fitnessData)
.getLines
.toList
.map(line => line.split(","))
val mp = loop(lines, Map())
println(mp)
}
}
expected result预期结果
Map(Oor Wullie Route3 (GCU) -> List((6,GCU,3.4), (5,Botanic Gardens,2.4), (4,Riverside Museum,5.4), (3,People's Palace,2.7), (2,Sir Chris Hoy Velodrome,3.8), (1,City Chambers,0.7)),
Oor Wullie Route2 (GCU) -> List((6,GCU,3.4), (5,Botanic Gardens,2.4), (4,Riverside Museum,5.4), (3,People's Palace,2.7), (2,Sir Chris Hoy Velodrome,3.8), (1,City Chambers,0.7)),
Oor Wullie Route (GCU) -> List((6,GCU,3.4), (5,Botanic Gardens,2.4), (4,Riverside Museum,5.4), (3,People's Palace,2.7), (2,Sir Chris Hoy Velodrome,3.8), (1,City Chambers,0.7)))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.