我有一个这种csv格式的字符串:
//> lines : String = a1 , 2 , 10
//| a2 , 2 , 5
//| a3 , 8 , 4
//| a4 , 5 , 8
//| a5 , 7 , 5
//| a6 , 6 , 4
//| a8 , 4 , 9
我想将此String转换为对象List,其中String的每一行代表对象List中的新条目。我可以想到如何做到这一点 -
将String分成多行并将每一行拆分为其csv标记。循环遍历每一行,并为每一行创建一个新对象并将其添加到List。但是我试图在功能上考虑这个问题而且我不确定从哪里开始。有什么指示吗?
答案 0 :(得分:4)
假设您从一个迭代器开始,为每一行生成一个String。如果您是从文件加载,则Source
类可以执行此操作;如果您已经开始使用val lines = input.split("\n")
String
这也适用于List,Seq等。Iterator
不是先决条件。
所以你映射输入来解析每一行
val lines = input split "\n"
val output = lines map { line => parse(line) }
或(无点式)
val output = lines map parse
您需要的只是parse
方法,以及应解析行的类型。案例类别是一个不错的选择:
case class Line(id: String, num1: Int, num2: Int)
所以解析。我将把结果包装在Try
中,这样你就可以捕获错误:
def parse(line: String): Try[Line] = Try {
//split on commas and trim whitespace
line.split(",").trim match {
//String.split produces an Array, so we pattern-match on an Array of 3 elems
case Array(id,n1,n2) =>
// if toInt fails it'll throw an Exception to be wrapped in the Try
Line(id, n1.toInt, n2.toInt)
case x => throw new RuntimeException("Invalid line: " + x)
}
}
将所有内容放在一起,最终输出为CC[Try[Line]]
,其中CC
是lines
的集合类型(例如Iterator,Seq等)
然后您可以隔离错误:
val (goodLines, badLines) = output.partition(_.isSuccess)
或者,如果您只想删除中间Try
并丢弃错误:
val goodLines: Seq[Line] = output collect { case Success(line) => line }
ALL TOGETHER
case class Line(id: String, num1: Int, num2: Int)
def parse(line: String): Try[Line] = Try {
line.split(",").trim match {
case Array(id,n1,n2) => Line(id, n1.toInt, n2.toInt)
case x => throw new RuntimeException("Invalid line: " + x)
}
}
val lines = input split "\n"
val output = lines map parse
val (successes, failures) = output.partition(_.isSuccess)
val goodLines = successes collect { case Success(line) => line }
答案 1 :(得分:3)
由于未提供样本输出,因此不确定这是否是您想要的确切输出。应该能够从中得到你想要的东西。
scala> val lines: String = """a1,2,10
| a2,2,5
| a3,8,4
| a4,5,8
| a5,7,5
| a6,6,4
| a8,4,9"""
lines: String =
a1,2,10
a2,2,5
a3,8,4
a4,5,8
a5,7,5
a6,6,4
a8,4,9
scala> case class Line(s: String, s2: String, s3: String)
defined class Line
scala> lines.split("\n").map(line => line.split(",")).map(split => Line(split(0), split(1), split(2)))
res0: Array[Line] = Array(Line(a1,2,10), Line(a2,2,5), Line(a3,8,4), Line(a4,5,8), Line(a5,7,5), Line(a6,6,4), Line(a8,4,9))