I am currently learning Scala and I am trying to read lines of text from a file and convert them into a map of type - Map[String, List[(Int,Int)]]
, but having difficulty getting there.
Example of text from file = London, -1:19, -2:21, 0:18, -3:24
I want it to be returned as - Map(London -> List((-1,19), (-2,21), (0,18), (-3,24))
I am able to get the city name by doing:
for (line <- Source.fromFile(filename).getLines()) {
val splitLine = line.split(",").map(_.trim)
val city = splitLine.head
But I'm not able to get much further after this, I can't split the rest of the values into a list of ints.
EDIT:
Adding the full method in for clarification
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
}
You can do that in one line as
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
should be
Map(London -> List((-1,19), (-2,21), (0,18), (-3,24)))
//Iterator[Map[String, (Int, Int}]]
result
is an Iterator
so you should change the return type accordingly
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
}
Iterators are not really a collection and are not safe so I would suggest you to return list instead as
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
}
Your comments suggested that you want
Not really how I would like it displayed as other cities added to the file will give me an output like:
List(Map(London -> List((-1,19), (-2,21), (0,18), (-3,24))), Map(Edinburgh -> List((-3,16), (-2, 19), (-1, 21)))
etc... instead ofMap(London -> List((-1,19), (-2,21), (0,18), (-3,24))), Edinburgh -> List((-3,16), (-2, 19), (-1, 21)))
almost like a key/value pair
For that all you need is .flatter.toMap
and change the return type to 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
}
You can do as follows to get a Map[String,List[(Int, Int)]]]
as you requested
for {
line <- Source.fromFile(filename).getLines()
val array = line.split(",")
}yield Map(array.head -> array.tail.toList.map(_.split(":").map(_.trim.toInt)).map(elem => (elem(0), elem(1))))
The biggest logic is in the tail management, to turn it to a tuple of Ints
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.