scala immutable.Map 的惯用“获取或更新”?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4385976/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
idiomatic "get or else update" for immutable.Map?
提问by IttayD
What is the idiomatic way of a getOrElseUpdate for immutable.Map instances?. I use the snippet below, but it seems verbose and inefficient
immutable.Map 实例的 getOrElseUpdate 的惯用方式是什么?我使用下面的代码段,但它似乎冗长且效率低下
var map = Map[Key, Value]()
def foo(key: Key) = {
val value = map.getOrElse(key, new Value)
map += key -> value
value
}
采纳答案by Debilski
Let me summarise your problem:
我总结一下你的问题:
- You want to call a method on a immutable data structure
- You want it to return some value andreassign a
var - Because the data structure is immutable, you'll need to
- return a new immutable data structure, or
- do the assignment inside the method, using a supplied closure
- 您想在不可变数据结构上调用方法
- 您希望它返回一些值并重新分配一个
var - 因为数据结构是不可变的,所以你需要
- 返回一个新的不可变数据结构,或
- 使用提供的闭包在方法内部进行赋值
So, either your signature has to look like
所以,要么你的签名看起来像
def getOrElseUpdate(key: K): Tuple2[V, Map[K,V]]
//... use it like
val (v, m2) = getOrElseUpdate(k)
map = m2
or
或者
def getOrElseUpdate(key: K, setter: (Map[K,V]) => Unit): V
//... use it like
val v = getOrElseUpdate(k, map = _)
If you can live with one of these solutions, you could add your own version with an implicit conversion but judging by the signatures alone, i wouldn't think any of these is in the standard library.
如果您可以接受这些解决方案之一,您可以添加您自己的带有隐式转换的版本,但仅从签名来看,我认为这些都不会出现在标准库中。
回答by Frank S. Thomas
I would probably implement a getOrElseUpdatedmethod like this:
我可能会实现这样的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)
}
which either returns the original map if mhas a mapping for keyor another map with the mapping key -> opadded. The definition of this method is similar to getOrElseUpdateof mutable.Map.
如果m有映射key或key -> op添加了映射的另一个映射,则返回原始映射。这种方法的定义类似于getOrElseUpdate的mutable.Map。
回答by Vasil Remeniuk
There's no such way - map mutation (update), when you're getting a map value, is a side effect (which contradicts to immutability/functional style of programming).
没有这样的方法 - 当您获得地图值时,地图突变(更新)是一种副作用(这与编程的不变性/功能风格相矛盾)。
When you want to make a new immutable map with the default value, if another value for the specified key doesn't exist, you can do the following:
当你想用默认值创建一个新的不可变映射时,如果指定键的另一个值不存在,你可以执行以下操作:
map + (key -> map.getOrElse(key, new Value))
回答by Daniel C. Sobral
Why not use withDefaultor withDefaultValueif you have an immutable map?
为什么不使用withDefault或者withDefaultValue如果你有一个不可变的地图?

