Предположим, вы начинаете с итератора, производящего одну строку для каждой строки. Source
класс может это сделать, если вы загружаете из файла, или вы можете использовать val lines = input.split("\n")
, если вы уже начиная со всем в одном String
Это также работает со списком, послед и т.д. 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
(например итератора , Seq и т.д.)
вы можете изолировать ошибки:
val (goodLines, badLines) = output.partition(_.isSuccess)
Или, если вы просто хотите, чтобы вырезать промежуточные Try
с и отбросить ошибки:
val goodLines: Seq[Line] = output collect { case Success(line) => line }
ВСЕ ВМЕСТЕ
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 }
это простой список понимание – gefei