如何在Scala中拆分要添加到地图的列表

如何在Scala中拆分要添加到地图的列表,scala,list,dictionary,functional-programming,Scala,List,Dictionary,Functional Programming,我有一些原始测试数据,我需要将其拆分为一个格式图: 映射[字符串,列表[(Int,Int,Int)]] 我已设法将数据作为列表读取,并将在下面给出一行数据的示例: Mon-18-June-2018,1:10:5,2:20:10,3:30:15,4:40:20,5:50:25 上面表示以下内容:一个日期,该日期的一段时间:步行时间:以更高速度行走的时间 因此,每组3个值(即1:10:5)应添加到地图的[Int,Int,Int]部分,日期为键 这是我到目前为止读取文件并将其添加到列表的代码:

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

映射[字符串,列表[(Int,Int,Int)]]

我已设法将数据作为列表读取,并将在下面给出一行数据的示例:

Mon-18-June-2018,1:10:5,2:20:10,3:30:15,4:40:20,5:50:25
上面表示以下内容:一个日期,该日期的一段时间:步行时间:以更高速度行走的时间

因此,每组3个值(即1:10:5)应添加到地图的[Int,Int,Int]部分,日期为键

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

    var mapBuffer: Map[String, List[(Int, Int, Int)]] = Map()

    val fitnessData = "C:\\Users\\ritch\\IdeaProjects\\Coursework\\src\\data.txt"

    val lines = Source.fromFile("C:\\Users\\ritch\\IdeaProjects\\Coursework\\src\\data.txt").getLines.toList
我想编写一个函数,用于将数据拆分并添加到地图,基本上是这样做的:

var key ="Mon-18-June-2018"
var newList = List((1,10,5),(2,20,10),(3,30,15),(4,40,20),(5,50,25))
mapBuffer = mapBuffer ++ Map(key -> newList)

如何将数据以所需格式添加到映射?

以下实现是一种通用实现,不依赖于运行时获得的参数数量

val line = "Mon-18-June-2018,1:10:5,2:20:10,3:30:15,4:40:20,5:50:25"
val arr = line.split(",")

val map = scala.collection.mutable.Map[String,List[List[Int]]]()
val key = arr(0)
val values = arr.toList.drop(1).map{
  case str : String =>
    str.split(":").map(_.toInt).foldLeft(List[Int]())(
      (acc,res) =>
        acc :+ res
    )
}

map += (key -> values)
这将为您提供如下输出:

res0: scala.collection.mutable.Map[String,List[List[Int]]] = Map(Mon-18-June-2018 -> List(List(1, 10, 5), List(2, 20, 10), List(3, 30, 15), List(4, 40, 20), List(5, 50, 25)))
res0: scala.collection.mutable.Map[String,List[(Int, Int, Int)]] = Map(Mon-18-June-2018 -> List((1,10,5), (2,20,10), (3,30,15), (4,40,20), (5,50,25)))
但是,如果您确信总是以1:10:2的格式获取参数,那么您可以直接使用元组实现,而不是折叠列表

val line = "Mon-18-June-2018,1:10:5,2:20:10,3:30:15,4:40:20,5:50:25"
val arr = line.split(",")

val map = scala.collection.mutable.Map[String,List[(Int,Int,Int)]]()
val key = arr(0)
val values = arr.toList.drop(1).map{
  case str : String =>
    str.split(":").map(_.toInt).foldLeft(List[Int]())(
      (acc,res) =>
        acc :+ res
    )
}.map(x => (x(0),x(1),x(2)))

map += (key -> values)
这将获取一个输出作为

res0: scala.collection.mutable.Map[String,List[List[Int]]] = Map(Mon-18-June-2018 -> List(List(1, 10, 5), List(2, 20, 10), List(3, 30, 15), List(4, 40, 20), List(5, 50, 25)))
res0: scala.collection.mutable.Map[String,List[(Int, Int, Int)]] = Map(Mon-18-June-2018 -> List((1,10,5), (2,20,10), (3,30,15), (4,40,20), (5,50,25)))

您可以使用regex提取所需的数据

val x = "Mon-18-June-2018,1:10:5,2:20:10,3:30:15,4:40:20,5:50:25"
val regex = "[0-9]+:[0-9]+:[0-9]+".r
println(Map(x.takeWhile(!_.equals(',')) -> regex
    .findAllIn(x)
    .toList
    .map(_.split(":").toVector).map{
        case Vector(a,b,c) => (a,b,c)
    }
))
输出:

Map(Mon-18-June-2018 -> List((1,10,5), (2,20,10), (3,30,15), (4,40,20), (5,50,25)))

这里有一个使用正则表达式/模式匹配的解决方案:

从您创建的列表开始:

val allLists: List[List[String]] = List(List("Mon-18-June-2018", "1:10:5", "2:20:10", "3:30:15", "4:40:20", "5:50:25"),
    List("Mon-19-June-2018", "22:10:5", "2:220:10", "3:33:15", "4:40:20", "5:50:25"))
我们为以下数字创建一个正则表达式:

val numberRegex = """(\d+):(\d+):(\d+)""".r.unanchored
现在,我们绘制列表:

val result: Map[String, List[(Int, Int, Int)]] = allLists.map {
    case date :: (numbers:Seq[String]) => date -> // the first entry is the date
      numbers.map { // map the rest (numbers list)
        case numberRegex(x, y, z) => (x.toInt, y.toInt, z.toInt) 
      }
  }.toMap
将打印:

Map(Mon-18-June-2018 -> List((1,10,5), (2,20,10), (3,30,15), (4,40,20), (5,50,25)), Mon-19-June-2018 -> List((22,10,5), (2,220,10), (3,33,15), (4,40,20), (5,50,25)))