【问题标题】:How to split a List to be added to a Map in Scala with Different Data Types如何拆分列表以添加到具有不同数据类型的 Scala 中的地图
【发布时间】:2020-07-25 10:44:56
【问题描述】:

我有一些原始测试数据需要拆分为格式图:

Map[String, List[(Int, String, Float)]]

我已经设法以列表的形式读入数据,并将在下面给出一行数据的示例:

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

以上表示如下:一条Route,一个阶段号:阶段名称:阶段总距离

所以每组 3 个值(即 1:City Chambers:5)都应该添加到地图的 [Int, String, Float] 部分,路线名称是关键。

这是我目前用于读取文件并将其添加到列表的代码:

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

我想编写一个函数来拆分数据并将其添加到地图中,基本上是这样做的:

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)

如何将数据添加到所需格式的地图中?

【问题讨论】:

  • 您需要检查mapBuffer中是否已经存在密钥,并将mapBuffer中的列表与新列表连接起来。

标签: list scala dictionary functional-programming


【解决方案1】:

我的建议是使用 foldLeft。比如:

  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)
  })

从空地图开始,为每一行添加键->值。 另外,在解析列表中的数据时尝试匹配表达式(listOfValues 部分正在这样做)。

【讨论】:

    【解决方案2】:

    这种方法适用于pattern matchingtail recursion。 我觉得效果很好。

    首先我将文件转换为List[Array[String]]

    其次,我调用循环以递归方式遍历列表并构建地图。

    循环函数中的第三个我调用 make List 以递归方式构建元组列表。

    举个例子:

    输入

    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
    

    代码

    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)
      }
    }
    

    预期结果

    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)))
    

    【讨论】:

      猜你喜欢
      • 2019-08-29
      • 2018-08-17
      • 2013-11-13
      • 1970-01-01
      • 1970-01-01
      • 2021-08-20
      • 1970-01-01
      • 2013-02-11
      • 2020-09-11
      相关资源
      最近更新 更多