将字符串转换为Map(String,List([Int,Int]))

时间:2018-04-04 13:31:03

标签: scala

我正在学习Scala,我正在尝试从文件中读取文本行并将其转换为类型为Map[String, List[(Int,Int)]]的地图,但很难到达。

来自file = London, -1:19, -2:21, 0:18, -3:24

的文字示例

我希望将其作为 - Map(London -> List((-1,19), (-2,21), (0,18), (-3,24))

返回

我可以通过以下方式获取城市名称:

for (line <- Source.fromFile(filename).getLines()) {
        val splitLine = line.split(",").map(_.trim)
        val city = splitLine.head

但是在此之后我无法进一步发展,我无法将其余的值拆分为一个整数列表。

编辑:

添加完整方法以澄清

def readFile(filename: String): Map[String, List[(Int, Int)]] = {
    val result = for (line <- Source.fromFile(filename).getLines(); array = line.split(",").map(_.trim)) yield Map(array.head -> array.tail.map(x => {
      val y = x.split(":"); (y(0).toInt, y(1).toInt)
    }).toList)
    result
  }

2 个答案:

答案 0 :(得分:1)

可以在一行中执行

val result = for (line <- Source.fromFile(filename).getLines(); array = line.split(",").map(_.trim)) yield Map(array.head -> array.tail.map(x => {val y = x.split(":"); (y(0).toInt, y(1).toInt)}).toList)

result应该是

Map(London -> List((-1,19), (-2,21), (0,18), (-3,24)))
//Iterator[Map[String, (Int, Int}]]

resultIterator,因此您应该相应地更改返回类型

def readFile(filename: String): Iterator[Map[String, List[(Int, Int)]]] = {
    val result = for (line <- Source.fromFile(filename).getLines(); array = line.split(",").map(_.trim)) yield Map(array.head -> array.tail.map(x => {
      val y = x.split(":"); (y(0).toInt, y(1).toInt)
    }).toList)
    result
  }

迭代器不是真正的集合而且不安全因此我建议您将列表改为

def readFile(filename: String): List[Map[String, List[(Int, Int)]]] = {
  val result = for (line <- Source.fromFile(filename).getLines(); array = line.split(",").map(_.trim)) yield Map(array.head -> array.tail.map(x => {
    val y = x.split(":"); (y(0).toInt, y(1).toInt)
  }).toList)
  result.toList
}

您的评论建议您想要

  

不是我想要显示的方式,因为添加到文件中的其他城市会给我一个输出:List(Map(London -> List((-1,19), (-2,21), (0,18), (-3,24))), Map(Edinburgh -> List((-3,16), (-2, 19), (-1, 21)))等...而不是Map(London -> List((-1,19), (-2,21), (0,18), (-3,24))), Edinburgh -> List((-3,16), (-2, 19), (-1, 21)))几乎像一个键/值对

为此,您只需.flatter.toMap并将返回类型更改为Map[String, List[(Int, Int)]]

def readFile(filename: String): Map[String, List[(Int, Int)]] = {
  val result = for (line <- Source.fromFile(filename).getLines(); array = line.split(",").map(_.trim)) yield Map(array.head -> array.tail.map(x => {
    val y = x.split(":"); (y(0).toInt, y(1).toInt)
  }).toList)
  result.toList.flatten.toMap
}

答案 1 :(得分:1)

您可以按照以下步骤获得<{1}},如您所要求的那样

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

最大的逻辑在于尾部管理,将它变成Ints元组