Vincent Tjeng
Vincent Tjeng

Reputation: 743

Scala Syntactic Sugar for converting to `Option`

When working in Scala, I often want to parse a field of type [A] and convert it to a Option[A], with a single case (for example, "NA" or "") being converted to None, and the other cases being wrapped in some.

Right now, I'm using the following matching syntax.

match {
  case "" => None
  case s: String => Some(s)
}
// converts an empty String to None, and otherwise wraps it in a Some.

Is there any more concise / idiomatic way to write this?

Upvotes: 6

Views: 245

Answers (3)

elm
elm

Reputation: 20435

A simple and intuitive approach includes this expression,

if (s.isEmpty) None else Some(s)

This assumes s labels the value to be otherwise matched (thanks to @RexKerr for the note).

Upvotes: 0

Rex Kerr
Rex Kerr

Reputation: 167921

There are a more concise ways. One of:

Option(x).filter(_ != "")
Option(x).filterNot(_ == "")

will do the trick, though it's a bit less efficient since it creates an Option and then may throw it away.

If you do this a lot, you probably want to create an extension method (or just a method, if you don't mind having the method name first):

implicit class ToOptionWithDefault[A](private val underlying: A) extends AnyVal {
  def optNot(not: A) = if (underlying == not) None else Some(underlying)
}

Now you can

scala> 47.toString optNot ""
res1: Option[String] = Some(47)

(And, of course, you can always create a method whose body is your match solution, or an equivalent one with if, so you can reuse it for that particular case.)

Upvotes: 10

Travis Brown
Travis Brown

Reputation: 139058

I'd probably use filterNot here:

scala> Option("hey").filterNot(_ == "NA")
res0: Option[String] = Some(hey)

scala> Option("NA").filterNot(_ == "NA")
res1: Option[String] = None

It requires you to think of Option as a collection with one or zero elements, but if you get into that habit it's reasonably clear.

Upvotes: 4

Related Questions