解析CSV时如何将Map键更改为Int?

问题描述 投票:0回答:1
val source = scala.io.Source.fromFile("src/main/Mapping.csv");
val data_map: Map[String, String] = source.getLines().map(csv=> (csv.split(",")(0),csv.split(",")(1))).toMap

当我从 CSV 文件中获取值时,它会创建一个 [String, String]。我如何使其成为[Int,String]?我见过有人说做类似的事情应该有效

val new_map = data_map.map { case (k, v) => (k.toInt,v )}

但它似乎不起作用,因为它会抛出一个

NumberFormatException
错误,指出第一个键需要是 Int 时是字符串。我的地图仍然是[String, String]。当我需要解析 CSV 文件时,如何使键成为整数值?

我的 CSV 文件就像这样:

1,2,
3,4,

等等。

编辑:更新了代码以更好地显示问题所在。根据反馈更改了它。当我制作新地图时,我收到 NumberFormatExceptionError 说它无法制作新地图,因为键是字符串,而我希望它们是整数。

scala csv hashmap
1个回答
1
投票

这一点已经在评论中提出,但由于媒体允许的简洁性,这一点可能会丢失,值得用更长的解释来扩展。

Scala 拥有强大的静态类型系统。因此,虽然技术上是可行的,但改变集合中值的类型会使您的代码相对尴尬。最重要的是,默认情况下,在 Scala 中你使用 immutable 集合,包括

Map
,这意味着这样做是不可能的(不诉诸反射,但你绝对不想去那里)。

在像 Scala 这样的语言中,从

Map[String, String]
Map[Int, String]
所采取的方法是完全返回一个新地图并继续使用它:

val data_map: Map[String, String] =
  source.getLines().map(csv => (csv.split(",")(0), csv.split(",")(1))).toMap

val data_map_with_int_keys: Map[Int, String] =
  data_map.map { case (k, v) => (k.toInt, v) }

在上面的代码片段中,

data_map
未更改(因为它是不可变的),而
data_map_with_int_keys
是您想要的地图。

一些补充说明:

  • 虽然乍一看不可变数据结构似乎很浪费,但事实是不可变数据可以共享,这意味着,例如,在幕后,地图的值不会改变,因此可以从原始地图和新的,减少不必要的复制
  • 您可以在 Scala 官方文档中阅读更多可变和不可变集合
  • 您可以在 Scastie 上使用上面的代码
  • 在 Scala 中,通常倾向于使用
    camelCase
    而不是
    snake_case
    ,但当然 YMMV 并坚持您所在项目的风格
  • 虽然从技术上来说并没有错误,但没有必要多次
    csv.split
    ,您可以执行以下操作(Scastie 上的代码):
val data_map: Map[String, String] =
  source.getLines().map(csv => {
    val fields = csv.split(",")
    (fields(0), fields(1))
  }).toMap
© www.soinside.com 2019 - 2024. All rights reserved.