immutable.Map实例的getOrElseUpdate的惯用方法是什么?我使用下面的代码片段,但它似乎冗长而低效
var map = Map[Key, Value]()
def foo(key: Key) = {
val value = map.getOrElse(key, new Value)
map += key -> value
value
}
答案 0 :(得分:13)
我可能会实现这样的getOrElseUpdated
方法:
def getOrElseUpdated[K, V](m: Map[K, V], key: K, op: => V): (Map[K, V], V) =
m.get(key) match {
case Some(value) => (m, value)
case None => val newval = op; (m.updated(key, newval), newval)
}
如果m
具有key
的映射或添加了映射key -> op
的其他地图,则返回原始地图。此方法的定义类似于getOrElseUpdate
的{{1}}。
答案 1 :(得分:9)
让我总结一下你的问题:
var
所以,你的签名必须看起来像
def getOrElseUpdate(key: K): Tuple2[V, Map[K,V]]
//... use it like
val (v, m2) = getOrElseUpdate(k)
map = m2
或
def getOrElseUpdate(key: K, setter: (Map[K,V]) => Unit): V
//... use it like
val v = getOrElseUpdate(k, map = _)
如果您可以使用其中一种解决方案,您可以使用隐式转换添加自己的版本,但仅通过签名判断,我认为这些都不在标准库中。
答案 2 :(得分:8)
没有这样的方法 - 当您获得地图值时,地图变异(更新)是副作用(与编程的不变性/功能样式相矛盾)。
如果要使用默认值创建新的不可变映射,如果指定键的另一个值不存在,则可以执行以下操作:
map + (key -> map.getOrElse(key, new Value))
答案 3 :(得分:2)
如果您有不可变的地图,为什么不使用withDefault
或withDefaultValue
?