У меня есть Iterable[String]
, представляющий строки в файле, и я хотел бы найти первую строку в этой последовательности, которая соответствует регулярному выражению, и вернуть числовое значение, извлеченное регулярным выражением. Файл достаточно большой, чтобы не было смысла загружать все это в память, а затем вызывать toString()
или что-то в этом роде, поэтому мне нужно будет пройти по нему строку за раз.
Вот что у меня (работает):
val RateRegex : Regex = ".....".r
def getRate(source : Source) : Option[Double] = {
import java.lang.Double._
for(line <- source.getLines() ) {
line match {
case RateRegex(rawRate) => return Some(parseDouble(rawRate))
case None => ()
}
}
return None
}
Это кажется мне безобразным. Это очень важно, и case None => ()
может быть заменено комментарием, который говорит: «Вы делаете это неправильно».
Я думаю, что хочу что-то вроде def findFirstWhereNonNone(p : Function[A,Option[B]]) => Option[B]
, где элементы коллекции имеют тип A
.
Существуют ли встроенные методы, которые позволили бы мне сделать это более функциональным способом? Должен ли я просто написать этот метод?
P.S. Пока я в этом, есть ли альтернатива использованию java.lang.Double.parseDouble
? Класс Scala Double
не раскрывает его.
P.P.S Я видел много постов на SO, в которых предлагалось, чтобы Source
API не использовался в производстве, но они все с 2008 и 2009 годов. Это все еще так? Если так, что я должен использовать для IO?
Обновление
Теперь у меня есть:
import util.matching.Regex.Groups
for{line <- source.getLines()
Groups(rawRate) <- RateRegex.findFirstMatchIn(line)} {
return Some(parseDouble(rawRate))
}
return None
что для меня намного лучше.