What is a quick safe way to convert a string to a numeric type, provided that the default value when conversion fails
I tried to use the generally recommended method, i.e. use Exceptions:
implicit class StringConversion(val s: String) { private def toTypeOrElse[T](convert: String=>T, defaultVal: T) = try { convert(s) } catch { case _: NumberFormatException => defaultVal } def toShortOrElse(defaultVal: Short = 0) = toTypeOrElse[Short](_.toShort, defaultVal) def toByteOrElse(defaultVal: Byte = 0) = toTypeOrElse[Byte](_.toByte, defaultVal) def toIntOrElse(defaultVal: Int = 0) = toTypeOrElse[Int](_.toInt, defaultVal) def toDoubleOrElse(defaultVal: Double = 0D) = toTypeOrElse[Double](_.toDouble, defaultVal) def toLongOrElse(defaultVal: Long = 0L) = toTypeOrElse[Long](_.toLong, defaultVal) def toFloatOrElse(defaultVal: Float = 0F) = toTypeOrElse[Float](_.toFloat, defaultVal) }
Using this utility class, I can now easily convert any String to a given numeric type and provide a default value if String is not a numeric type:
scala> "123".toIntOrElse() res1: Int = 123 scala> "abc".toIntOrElse(-1) res2: Int = -1 scala> "abc".toIntOrElse() res3: Int = 0 scala> "3.14159".toDoubleOrElse() res4: Double = 3.14159 ...
While it works beautifully, this approach does not seem to scale very well, probably due to the Exceptions mechanism:
scala> for (i<-1 to 10000000) "1234".toIntOrElse()
takes about 1 second to complete, whereas
scala> for (i<-1 to 10000000) "abcd".toIntOrElse()
takes about 1 minute !
I suggest that another approach would be to not rely on the exceptions thrown by the methods toInt, toDouble, ....
Can this be achieved by checking if the string is "of this type"? Of course, you can iterate over the String characters and check that they are numbers (see, for example, this example ), but then what about other number formats (double, float, hex, octal, ...)?