scala更好的map getOrElse语法

时间:2012-09-20 00:26:21

标签: scala

有没有更好的方法来编写下面的代码?

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

对内联代码感兴趣

val t = map.get('type).getOrElse("").????

5 个答案:

答案 0 :(得分:31)

Map有自己的getOrElse方法,因此您只需撰写以下内容:

val t = map.getOrElse('type, "")

在第一个例子中,它与t的定义完全相同。


解决您的评论:如果您知道您的地图永远不会将空字符串作为值包含,您可以使用以下内容添加"prefix"

map.get('type).map("prefix" + _).getOrElse("")

或者,如果您使用的是Scala 2.10:

map.get('type).fold("")("prefix" + _)

如果您的地图可以具有""值,则此版本的行为与您的版本略有不同,因为它会为这些值添加前缀。如果您想要在单行中与您的版本完全相同的行为,您可以编写以下内容:

map.get('type).filter(_.nonEmpty).map("prefix" + _).getOrElse("")

这可能没有必要,但听起来你不希望你的地图中有空字符串。

答案 1 :(得分:4)

值得注意的是,在某些情况下,您可以通过一次.getOrElse来代替多个常见.withDefaultValue次使用。

val map = complexMapCalculation().withDefaultValue("")

val t = map('type)

我不会说这是每次都应该做的事情,但它可以很方便。

答案 2 :(得分:1)

您还可以使用Scalaz Zero类型类,因此您的代码如下所示。一元运算符在OptionW上定义。

val t = ~map.get('type)                 // no prefix
val t = ~map.get('type).map("prefix"+_) // prefix

这是一个示例会话:

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 = ""

答案 3 :(得分:0)

在阅读本书Play for Scala时,我选择了在控制器中定义的代码段,这可能是 getOrElse 的更好语法。

def show(ean: Long) = Action { implicit request =>

  Product.findByEan(ean).map { product =>
    Ok(views.html.products.details(product))
  }.getOrElse(NotFound)

}

其中, Product.findByEan(ean:Long)被定义为

def findByEan(ean: Long) = products.find(_ean == ean)

答案 4 :(得分:0)

 val t = map.getOrElse("type","") match {case value if value !="" => s"prefix${value}" case _ => ""}