Mylies
Mylies

Reputation: 446

Pattern matching to convert string to Long

I have a string that I need to convert into a long if it is not empty or blank. If it either can't be converted(it fails during conversion) or the string is empty or blank I need to run a secondary function. Right now I have a if statement but I would like to convert it to pattern matching if possible to make my code a little cleaner.

Heres what I have right now

val stringToConvert = "1234"

if (!stringToConvert.isBlank && !stringToConvert.isEmpty) {
  try {
    val converted = stringToConvert.toLong
    doThingWithConvertedValue(converted)
  }
  catch {
    case _: Throwable =>
      Log.error("Encountered error while trying to convert string to long")
  }
}
else {
  doOtherThing()
}

Whats the best way to do this?

Upvotes: 0

Views: 516

Answers (5)

Zvi Mints
Zvi Mints

Reputation: 1142

Considering the following functions:

def doThingWithConvertedValue(l: Long) = println (s"doThingWithConvertedValue($l)")
def doOtherThing() =  println ("doOtherThing()")

Your code can be transferred to the following:

Try(stringToConvert).filter(stringToConvert => !stringToConvert.isBlank && stringToConvert.nonEmpty).fold(
   sBlankOrEmpty => doOtherThing(),
   nEmpty => Try(doThingWithConvertedValue(nEmpty.toLong)).getOrElse {
     Log.error("Encountered error while trying to convert string to long")
   }
  )

Outputs:

"1234" => doThingWithConvertedValue(1234)
"notConvertable" => Encountered error while trying to convert string to long
"" => doOtherThing()

If you prefer using Pattern matching, you can do it as follows:

val stringToConvert = "123s"
stringToConvert match {
  case sBlankOrEmpty if sBlankOrEmpty.isBlank || sBlankOrEmpty.isEmpty => doOtherThing()
  case canBeLong if Try(canBeLong.toLong).isSuccess => doThingWithConvertedValue(canBeLong.toLong)
  case _ => Log.error("Encountered error while trying to convert string to long")
}

Note:

  1. doThingWithConvertedValue can throw an exception (which you didnt recover properly for that case in your main file)
  2. .toLong is used twice O(n) Each, but if its fine for you i guess its pretty readable

Upvotes: 2

jwvh
jwvh

Reputation: 51271

I'm going to suggest that you don't need a pattern match. Just fold() over a Try.

util.Try(stringToConvert.toLong)
  .fold(exptn => {
    //Log.error() and doOtherThing() go here depending on requirements
    if (stringToConvert.isEmpty) ... //only when empty
    else                         ... //only when non-empty
    ... //do this regardless of empty status
  },doThingWithConvertedValue)

Upvotes: 2

Tomer Shetah
Tomer Shetah

Reputation: 8539

You can do:

val stringToConvert = "1234"

Try(doThingWithConvertedValue(stringToConvert.toLong)).getOrElse {
  println("Encounted error while trying to convert string to long")
  doOtherThing() 
}

Code run at Scastie.

Upvotes: 1

I would do something like this:

val stringToConvert = "1234"

Option(stringToConvert)
  .map(_.trim)
  .filter(_.isEmpty)
  .fold(ifEmpty =  doOtherThing() { str =>
    trs
      .toLongOption
      .fold(ifEmpty = Log.error("Encounted error while trying to convert string to long"))
           (doThingWithConvertedValue)
  }

Upvotes: 2

Ava
Ava

Reputation: 838

Try this:

import scala.util.{Try, Success, Failure}

val stringToConvert = "1234"

Try(stringToConvert.toLong) match {
  case Success(value)                        => doThingWithConvertedValue(value)
  case Failure(_) if stringToConvert.isBlank => doOtherThing()
  case Failure(exception) => 
    Log.error(s"Encounted error while trying to convert string to long: $exception")
}

Please note that isBlank already covers isEmpty case.

Upvotes: 3

Related Questions