is there a better way to write the code below?
val t = map.get(\'type).getOrElse(\"\");
if (t != \"\") \"prefix\" + t;
be interested in inline
It's also worth noting that, in certain cases, you can replace multiple common .getOrElse
usages with one .withDefaultValue
call.
val map = complexMapCalculation().withDefaultValue("")
val t = map('type)
I wouldn't say this is something that should be done every time, but it can be handy.
While reading the book Play for Scala
, I picked up this code snippet that was defined in a controller, which might be a better syntax for getOrElse.
def show(ean: Long) = Action { implicit request =>
Product.findByEan(ean).map { product =>
Ok(views.html.products.details(product))
}.getOrElse(NotFound)
}
In which, the Product.findByEan(ean: Long) was defined like
def findByEan(ean: Long) = products.find(_ean == ean)
Map
has its own getOrElse
method, so you can just write the following:
val t = map.getOrElse('type, "")
Which accomplishes the same thing as the definition of t
in your first example.
To address your comment: If you know your map will never contain the empty string as a value, you can use the following to add the "prefix"
:
map.get('type).map("prefix" + _).getOrElse("")
Or, if you're using Scala 2.10:
map.get('type).fold("")("prefix" + _)
If your map can have ""
values, this version will behave a little differently than yours, since it will add the prefix to those values. If you want exactly the same behavior as your version in a one-liner, you can write the following:
map.get('type).filter(_.nonEmpty).map("prefix" + _).getOrElse("")
This probably isn't necessary, though—it sounds like you don't expect to have empty strings in your map.
You could also use the Scalaz Zero typeclass so your code would look like below. The unary operator is defined on OptionW.
val t = ~map.get('type) // no prefix
val t = ~map.get('type).map("prefix"+_) // prefix
Here's an example session:
scala> import scalaz._; import Scalaz._
import scalaz._
import Scalaz._
scala> val map = Map('type -> "foo")
map: scala.collection.immutable.Map[Symbol,java.lang.String] = Map('type -> foo)
scala> ~map.get('type)
res3: java.lang.String = foo
scala> ~map.get('notype)
res4: java.lang.String = ""
scala> ~map.get('type).map("prefix"+_)
res5: java.lang.String = prefixfoo
scala> ~map.get('notype).map("prefix"+_)
res6: java.lang.String = ""