Scala将Array[String]转换为case class

6

虽然这是一个初学者的问题,但我经常需要处理文件,逐行解析并将其转换为类,以便我可以更加面向对象地使用它。在Java中,现在在Scala中我也是这样做的。

case class ABC(v1: Int, v2: String)
val str = line.split("\t")
val v1 = str(0).toInt
val v2 = str(1)
ABC(v1, v2)

有没有更简单的方式可以从数组创建case class,而不是像这样冗长的方式?因为我总是需要处理大量的字段,所以这变得非常乏味。


1
看看product-collections库。它有很好的csv转换为case类序列功能 - Odomontois
1个回答

6

在伴生对象中定义一个parse方法,它接受一个字符串并提取值以构建实例。

import util._

case class ABC(v1: Int, v2: String)

object ABC {
  def parse(s: String): Try[ABC] = {
    val Array(v1,v2,_*) = s.split("\t")
    Try(ABC(v1.toInt, v2))
  }
}

注意,v1 被转换为 Int,同时我们从分割的字符串中提取了前两个项目,但是可以提取任意数量的项目并将其转换为所需类型。

因此,有效的用法包括:

val v = ABC.parse("12\t ab")

我建议将其命名为其他名称,而不是 apply(例如 parse),因为许多人会期望 apply 直接使用 case class 的成员,并且绝对不会在正常输入时失败并引发异常。 - Travis Brown
@TravisBrown 謝謝,同意命名apply這個方法會產生誤導的含義(意料之外的語義 :) 請注意更新... - elm
谢谢,我觉得还可以(我仍然更喜欢结果是Try[ABC],但那更多地是个人口味的问题)。 - Travis Brown
好的,这个示例展示了在一个地方(对象)中解析逻辑,但在我的情况下并没有太多用处,因为我只迭代每个文件一次。我可以只做ABC(arr(0)。toInt,arr(1))。我同意elm的建议更面向对象,我会更喜欢那样。但我想要的是一种简单直接的方法,将数组元素按照相同顺序转换为案例类。即arr(0)被分配给案例类的第一个元素,依此类推。它还应该进行类型转换,并在无法解析时抛出编译或运行时错误。 - nir
@elm,谢谢! - Pyd

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接