Any DRY way to perform these functions that convert numbers with default settings?

I have a number of such functions:

  // Convert a string to integer, defaulting to 0 if it fails
  def safeToInt(s: String): Int = try {
      s.toInt
    } catch {
      case _: NumberFormatException => 0
    }

  // Convert a string to long, defaulting to 0 if it fails
  def safeToLong(s: String): Long = try {
      s.toLong
    } catch {
      case _: NumberFormatException => 0
    }

  // Convert a string to double, defaulting to 0 if it fails
  def safeToDouble(s: String): Double = try {
      s.toDouble
    } catch {
      case _: NumberFormatException => 0
    }

Any way to make this cleaner? They essentially do the same thing, except for one line.

+4
source share
3 answers

You can use scala.util.Try

   import util.Try

   // Convert a string to integer, defaulting to 0 if it fails

   def safeToInt(s: String): Int = Try(s.toInt).getOrElse(0)

   // Convert a string to long, defaulting to 0 if it fails
   def safeToLong(s: String): Long = Try(s.toLong).getOrElse(0L)

   // Convert a string to double, defaulting to 0 if it fails
   def safeToDouble(s: String): Double = Try(s.toDouble).getOrElse(0.0)
+2
source

You can use Numericto avoid duplicate scratch.

import scala.util.Try

def safeToNumeric[A: Numeric](f: String => A)(s: String): A =
  Try(f(s)).getOrElse(implicitly[Numeric[A]].zero)

val safeToInt = safeToNumeric(_.toInt)(_)
val safeToLong = safeToNumeric(_.toLong)(_)
val safeToDouble = safeToNumeric(_.toDouble)(_)

safeToInt("4") // 4
safeToDouble("a") // 0.0

Unfortunately, Numericthe parsing method also does not give you, but you can create the corresponding class type yourself ...

case class Parser[A](parse : String => A)

implicit val intParser = Parser(_.toInt)
implicit val longParser = Parser(_.toLong)
implicit val doubleParser = Parser(_.toDouble)

... and then you can write one method that works for all types.

def safeTo[A: Parser : Numeric](s: String): A =
  Try(implicitly[Parser[A]].parse(s))
    .getOrElse(implicitly[Numeric[A]].zero)

safeTo[Int]("4") // 4
safeTo[Double]("a") // 0.0
+4
source

, , , . " - " , .

 import scala.util.Try

 def safeConverter[A](convert: String => A, default: A) = { input: String =>
    Try(convert(input)).getOrElse(default)
 }

 val safeToInt = safeConverter(_.toInt, 0)
 val safeToLong = safeConverter(_.toLong, 0L)
 val safeToDouble = safeConverter(_.toDouble, 0.0)

 safeToInt("334") // Returns 334
 safeToInt("this is not a number") // Returns 0

converter returns a function that performs a String conversion with a default value in case of an exception.

You can use this converterfor any conversion that potentially throws an exception, not just numeric values.

+1
source

Source: https://habr.com/ru/post/1545792/


All Articles