scala better syntax for map getOrElse

前端 未结 4 1872
南方客
南方客 2021-02-05 10:29

is there a better way to write the code below?

val t = map.get(\'type).getOrElse(\"\"); 
if (t != \"\") \"prefix\" + t;

be interested in inline

相关标签:
4条回答
  • 2021-02-05 10:56

    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.

    0 讨论(0)
  • 2021-02-05 10:56

    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)
    
    0 讨论(0)
  • 2021-02-05 11:04

    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.

    0 讨论(0)
  • 2021-02-05 11:14

    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 = ""
    
    0 讨论(0)
提交回复
热议问题