来自测试文件的 Scala 映射
Scala Map from Test File
希望从测试文件创建 Scala 映射。文本文件的示例(其中的几行)如下所示:
Alabama (9),Democratic:849624,Republican:1441170,Libertarian:25176,Others:7312
Alaska (3),Democratic:153778,Republican:189951,Libertarian:8897,Others:6904
Arizona (11),Democratic:1672143,Republican:1661686,Libertarian:51465,Green:1557,Others:475
我得到的地图缓冲区如下:
var mapBuffer: Map[String, List[(String, Int)]] = Map()
请注意,派对值以冒号分隔。
我正在尝试读取文件内容并将数据存储在映射结构中,其中文件的每一行都用于构造一个以日期为键、以元组列表为值的映射条目。结构的类型应该是 Map[String, List[(String,Int)]].
基本上只是试图从文件中创建每一行的地图,但我不太正确。我尝试了下面但没有运气 - 我认为 'val lines' 应该是一个数组而不是迭代器。
val stream : InputStream = getClass.getResourceAsStream("")
val lines: Iterator[String] = scala.io.Source.fromInputStream(stream).getLines
var map: Map[String, List[(String, Int)]] = lines
.map(_.split(","))
.map(line => (line(0).toString, line(1).toList))
.toMap
这似乎可以完成这项工作。 (Scala 2.13.x)
val stateVotes =
util.Using(io.Source.fromFile("votes.txt")){
val PartyVotes = "([^:]+):(\d+)".r
_.getLines()
.map(_.split(",").toList)
.toList
.groupMapReduce(_.head)(_.tail.collect{
case PartyVotes(p,v) => (p,v.toInt)})(_ ++ _)
} //file is auto-closed
//stateVotes: Try[Map[String,List[(String, Int)]]] = Success(
// Map(Alabama (9) -> List((Democratic,849624), (Republican,1441170), (Libertarian,25176), (Others,7312))
// , Arizona (11) -> List((Democratic,1672143), (Republican,1661686), (Libertarian,51465), (Green,1557), (Others,475))
// , Alaska (3) -> List((Democratic,153778), (Republican,189951), (Libertarian,8897), (Others,6904))))
在这种情况下,州名后面的数字将被保留。这可以改变。
不,迭代器很好(实际上比列表好),
您只需要也拆分值即可创建这些元组。
lines
.map(_.split(","))
.map { case l =>
l.head -> l.tail.toList.map(_.split(":"))
.collect { case Seq(a,b) => a -> b.toInt }
}
.toMap
一种在我看来更美观的替代方法是尽早转换为地图,然后使用 mapValues
(我个人非常喜欢
更喜欢短的 lambdas)。缺点是 mapValues
是懒惰的,所以你最终
最后必须执行 .toMap
两次才能强制执行:
lines
.map(_.split(","))
.map { case l => l.head -> l.tail.toList }
.toMap
.mapValues(_.split(":"))
.mapValues(_.collect { case Seq(a,b) => a -> b.toInt })
.toMap
希望从测试文件创建 Scala 映射。文本文件的示例(其中的几行)如下所示:
Alabama (9),Democratic:849624,Republican:1441170,Libertarian:25176,Others:7312
Alaska (3),Democratic:153778,Republican:189951,Libertarian:8897,Others:6904
Arizona (11),Democratic:1672143,Republican:1661686,Libertarian:51465,Green:1557,Others:475
我得到的地图缓冲区如下:
var mapBuffer: Map[String, List[(String, Int)]] = Map()
请注意,派对值以冒号分隔。
我正在尝试读取文件内容并将数据存储在映射结构中,其中文件的每一行都用于构造一个以日期为键、以元组列表为值的映射条目。结构的类型应该是 Map[String, List[(String,Int)]].
基本上只是试图从文件中创建每一行的地图,但我不太正确。我尝试了下面但没有运气 - 我认为 'val lines' 应该是一个数组而不是迭代器。
val stream : InputStream = getClass.getResourceAsStream("")
val lines: Iterator[String] = scala.io.Source.fromInputStream(stream).getLines
var map: Map[String, List[(String, Int)]] = lines
.map(_.split(","))
.map(line => (line(0).toString, line(1).toList))
.toMap
这似乎可以完成这项工作。 (Scala 2.13.x)
val stateVotes =
util.Using(io.Source.fromFile("votes.txt")){
val PartyVotes = "([^:]+):(\d+)".r
_.getLines()
.map(_.split(",").toList)
.toList
.groupMapReduce(_.head)(_.tail.collect{
case PartyVotes(p,v) => (p,v.toInt)})(_ ++ _)
} //file is auto-closed
//stateVotes: Try[Map[String,List[(String, Int)]]] = Success(
// Map(Alabama (9) -> List((Democratic,849624), (Republican,1441170), (Libertarian,25176), (Others,7312))
// , Arizona (11) -> List((Democratic,1672143), (Republican,1661686), (Libertarian,51465), (Green,1557), (Others,475))
// , Alaska (3) -> List((Democratic,153778), (Republican,189951), (Libertarian,8897), (Others,6904))))
在这种情况下,州名后面的数字将被保留。这可以改变。
不,迭代器很好(实际上比列表好), 您只需要也拆分值即可创建这些元组。
lines
.map(_.split(","))
.map { case l =>
l.head -> l.tail.toList.map(_.split(":"))
.collect { case Seq(a,b) => a -> b.toInt }
}
.toMap
一种在我看来更美观的替代方法是尽早转换为地图,然后使用 mapValues
(我个人非常喜欢
更喜欢短的 lambdas)。缺点是 mapValues
是懒惰的,所以你最终
最后必须执行 .toMap
两次才能强制执行:
lines
.map(_.split(","))
.map { case l => l.head -> l.tail.toList }
.toMap
.mapValues(_.split(":"))
.mapValues(_.collect { case Seq(a,b) => a -> b.toInt })
.toMap