Reputation: 743
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
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
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
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