Как найти, если Scala String обрабатывается как Double или нет?
Предположим, что у меня есть строка в scala, и я хочу попытаться разобрать ее.
Я знаю, что я могу просто вызвать toDouble
, а затем поймать исключение формата java num, если это не удается, но есть ли более чистый способ сделать это? Например, если была функция parseDouble
, которая вернула Option[Double]
, это было бы квалифицировано.
Я не хочу помещать это в свой собственный код, если он уже существует в стандартной библиотеке, и я просто ищу его в неправильном месте.
Спасибо за любую помощь, которую вы можете предоставить.
Ответы
Ответ 1
Или просто
def parseDouble(s: String) = try { Some(s.toDouble) } catch { case _ => None }
Необычная версия:
case class ParseOp[T](op: String => T)
implicit val popDouble = ParseOp[Double](_.toDouble)
implicit val popInt = ParseOp[Int](_.toInt)
// etc.
def parse[T: ParseOp](s: String) = try { Some(implicitly[ParseOp[T]].op(s)) }
catch {case _ => None}
scala> parse[Double]("1.23")
res13: Option[Double] = Some(1.23)
scala> parse[Int]("1.23")
res14: Option[Int] = None
scala> parse[Int]("1")
res15: Option[Int] = Some(1)
Ответ 2
Scalaz предоставляет метод расширения parseDouble
на String
s, который дает значение типа Validation[NumberFormatException, Double]
.
scala> "34.5".parseDouble
res34: scalaz.Validation[NumberFormatException,Double] = Success(34.5)
scala> "34.bad".parseDouble
res35: scalaz.Validation[NumberFormatException,Double] = Failure(java.lang.NumberFormatException: For input string: "34.bad")
Вы можете преобразовать его в Option
, если это необходимо.
scala> "34.bad".parseDouble.toOption
res36: Option[Double] = None
Ответ 3
scala> import scala.util.Try
import scala.util.Try
scala> def parseDouble(s: String): Option[Double] = Try { s.toDouble }.toOption
parseDouble: (s: String)Option[Double]
scala> parseDouble("3.14")
res0: Option[Double] = Some(3.14)
scala> parseDouble("hello")
res1: Option[Double] = None
Ответ 4
Вы можете попробовать использовать util.control.Exception.catching
, который возвращает тип Either
.
Таким образом, используя следующие данные, получим левую упаковку a NumberFormatException
или правую упаковку a Double
import util.control.Exception._
catching(classOf[NumberFormatException]) either "12.W3".toDouble
Ответ 5
Нет ничего подобного не только в Scala, но даже в базовой Java.
Вот фрагмент кода, который делает это без исключений, хотя:
def parseDouble(s: String)(implicit nf: NumberFormat) = {
val pp = new ParsePosition(0)
val d = nf.parse(s, pp)
if (pp.getErrorIndex == -1) Some(d.doubleValue) else None
}
Использование:
implicit val formatter = NumberFormat.getInstance(Locale.ENGLISH)
Console println parseDouble("184.33")
Console println parseDouble("hello, world")
Ответ 6
К сожалению, это не в стандартной библиотеке. Вот что я использую:
class SafeParsePrimitive(s: String) {
private def nfe[T](t: => T) = {
try { Some(t) }
catch { case nfe: NumberFormatException => None }
}
def booleanOption = s.toLowerCase match {
case "yes" | "true" => Some(true)
case "no" | "false" => Some(false)
case _ => None
}
def byteOption = nfe(s.toByte)
def doubleOption = nfe(s.toDouble)
def floatOption = nfe(s.toFloat)
def hexOption = nfe(java.lang.Integer.valueOf(s,16))
def hexLongOption = nfe(java.lang.Long.valueOf(s,16))
def intOption = nfe(s.toInt)
def longOption = nfe(s.toLong)
def shortOption = nfe(s.toShort)
}
implicit def string_parses_safely(s: String) = new SafeParsePrimitive(s)
Ответ 7
Я обычно бывал с "на месте". Попробуйте:
def strTimesTen (s: String) = for (d <- Try(s.toDouble)) yield d * 10
strTimesTen("0.1") match {
Success(d) => println( s"It is $d" )
Failure(ex) => println( "I've asked for a number!" )
}
Обратите внимание, что вы можете выполнить дальнейшие вычисления в for и любом исключении, которые будут проектироваться в Failure (ex). AFAIK - это идиоматический способ обработки последовательности ненадежных операций.