假设我有一个函数返回一个不可变的Map(下面是getMap
),我有两个选项,如果设置了该选项,我希望在地图中添加一个条目,否则保持地图不被修改。
所以在非功能性代码中(就像你在java中编写的那样):
def getMap(): Map[String, String] = {
Map(
"name" -> "My Name",
"age" -> "80")
}
def testJavaLink() {
val o1: Option[String] = Some("This one is set")
val o2: Option[String] = None
var mutableResult: mutable.Map[String, String] = mutable.Map() ++ getMap()
if (o1.isDefined) {
mutableResult("option1") = o1.get
}
if (o2.isDefined) {
mutableResult("option2") = o2.get
}
val result: Map[String, String] = mutableResult.toMap
}
这段代码显然不是很像scala,所以我尝试使用map-functions:
def test1() {
val o1: Option[String] = Some("This one is set")
val o2: Option[String] = None
val result: Map[String, String] = getMap() ++ (if (o1.isDefined) List(("option1", o1.get)) else List()) ++ (if (o2.isDefined) List(("option2", o2.get)) else List())
}
但这段代码可读性很差。
如何使用可读scala实现类似的功能?对于列表,有一个很好的语法(它利用了一个事实,即Option可以变成一个Iterable,它有一个或零个元素)。但是我不知道在使用地图时如何使用它。
答案 0 :(得分:3)
尝试:
val result = getMap ++ o1.map("option1" -> _) ++ o2.map("option2" -> _)
->
只需创建Tuple2
(对)
所以o1.map("option1" -> _)
会返回Option[(String,String)]
None
如果o1
为None
,则为Some(("option1", value))
。
最后,Option[A]
可以隐式转换为Iterable[A]
,如果Option[A]
为None
且List[A]
只包含一个元素,则该Option[(String,String)]
为空。因此Iterable[(String,String)]
会转换为Map[String,String]
。后者可以使用++
添加到{{1}}。
答案 1 :(得分:1)
您可以map
将Option
转换为Tuple
,然后致电toMap
和++
:
val o1: Option[String] = Some("This one is set")
val o2: Option[String] = None
val result = getMap ++ o1.map(o => ("option1", o)).toMap ++ o2.map(o => ("option2", o)).toMap