多个if else语句从Scala中的映射中获取非空值

时间:2015-03-18 19:21:05

标签: scala scala-collections

我有一个字符串到字符串映射,其值可以是一个空字符串。我想为变量分配一个非空值,以便在某处使用它。有没有更好的方法在Scala中写这个?

import scala.collection.mutable
var keyvalue = mutable.Map.empty[String, String]
keyvalue += ("key1" -> "value1")

var myvalue = ""
if (keyvalue.get("key1").isDefined &&
    keyvalue("key1").length > 0) {
  myvalue = keyvalue("key1")
}
else if (keyvalue.get("key2").isDefined &&
    keyvalue("key2").length > 0) {
  myvalue = keyvalue("key2")
}
else if (keyvalue.get("key3").isDefined &&
    keyvalue("key3").length > 0) {
  myvalue = keyvalue("key3")
}

2 个答案:

答案 0 :(得分:8)

更惯用的方法是使用filter检查Option中包含的字符串的长度,然后orElsegetOrElse以分配给val。一个粗略的例子:

def getKey(key: String): Option[String] = keyvalue.get(key).filter(_.length > 0)

val myvalue: String = getKey("key1")
    .orElse(getKey("key2"))
    .orElse(getKey("key3"))
    .getOrElse("")

这里使用任意回退键列表的方式类似。使用viewcollectFirst,我们只会根据需要评估keyvalue.get次数(或者如果没有匹配则全部评估)。

val myvalue: String = List("key1", "key2", "key3").view
    .map(keyvalue.get)
    .collectFirst { case Some(value) if(value.length > 0) => value } 
    .getOrElse("")

答案 1 :(得分:0)

嗯,似乎花了太长时间设计一个通用的解决方案,其他答案被接受了,但在这里:

     def getOrTryAgain(map: mutable.Map[String, String], keys: List[String]): Option[String] =
     {
        if(keys.isEmpty)
           None
        else
           map.get(keys.head).filter(_.length > 0).orElse(getOrTryAgain(map, keys.tail))
     }
     val myvalue2 = getOrTryAgain(keyvalue, List("key1", "key2", "key3"))

这个可以用来检查任意数量的键。