我正在使用一个我无法更改的api返回一个2元素的映射,其中一个键始终存在,但另一个键/值对是动态的,我正在尝试将它们解压缩到一个case类中。下面的代码有效,但真的很难看:
case class Foo(name: String, key: String, value: String)
def fooFromMap(item: Map[String, String]): Option[Foo] = {
var name: String = null
var key: String = null
var value: String = null
item.foreach {
case ("name", v) => name = v
case (k, v) => key = k; value = v
}
if(name != null && key != null && value != null) Some(Foo(name, key, value))
else None
}
有更好的方法吗?
答案 0 :(得分:3)
以下是等效的,更具惯用性:
def fooFromMap(item: Map[String, String]): Option[Foo] = for {
name <- item get "name"
(k, v) <- (item - "name").headOption
} yield Foo(name, k, v)
如果item get "name"
或(item - "name").headOption
显示为空,则结果为空 - 否则您将获得所需的Foo
。
答案 1 :(得分:2)
如果我理解正确,Map
始终是name
键,零或一个键值对,对吧?如果是,你可以这样做:
def fooFromMap(map: Map[String, String]) =
map.get("name").map { name =>
val (key, value) = (map - "name").head
Foo(name, key, value)
}
如果您还需要检查Map
是否有第二对(如果没有,则返回None
),那么:
def fooFromMap(map: Map[String, String]) = for {
name <- map.get("name")
(key, value) <- (map - "name").headOption
} yield Foo(name, key, value)
我倾向于选择第二个片段,因为它更加惯用,并且在Scala中使用了强大的for
推理。
答案 2 :(得分:0)
def fooFromMap(map: Map[String, String]): Option[Foo] = {
val data = m.find(_._1 != "name").getOrElse (null, null)
Foo(m.getOrElse("name", null), data._1, data._2) match {
case f: Foo if (f.name != null && f.key != null && f.value != null) => Some(f)
case _ => None
}
}