Rom*_*nko 13 containers dictionary scala
我知道几个类似的问题.它们对我没有帮助 - 如果没有现有密钥,代码就不起作用.
我只需要一些很好的方法来附加Map,将值添加到现有密钥(如果它确实存在)或将其作为新密钥(如果map不包含适当的密钥).
以下代码有效,但我不喜欢它:
val a = collection.mutable.Map(("k1" -> 1), ("k2" -> 5))
val key = "k1"
val elem = a.get(key)
if (elem == None) {
a += ("k5" -> 200)
} else {
a.update(key, elem.get + 5)
}
Run Code Online (Sandbox Code Playgroud)
有没有更好的一点?当前的Scala版本是2.10.4,我目前无法切换到2.11.可变图不是100%限制,而是优选的.
例如,这是类似的问题,但我还需要考虑不存在的那个不存在的密钥的情况.至少我们应该理解a.get(key)可能是None或添加一些更好的方法.好主意|+|但是我想保留基本的Scala 2.10.x.
dk1*_*k14 14
最简单的方法:
a += a.get(key).map(x => key -> (x + 5)).getOrElse("k5" -> 200)
Run Code Online (Sandbox Code Playgroud)
一般来说:
a += a.get(k).map(f).map(k -> _).getOrElse(kv)
Run Code Online (Sandbox Code Playgroud)
如果您的字典是不可变的,则相同:
m + m.get(k).map(f).map(k -> _).getOrElse(kv)
Run Code Online (Sandbox Code Playgroud)
所以我认为没有理由在这里使用可变集合.
如果你不喜欢这些Option.map东西:
m + (if (m.contains(k)) k -> f(m(k)) else kv)
Run Code Online (Sandbox Code Playgroud)
请注意,有一整类可能的变化:
k1 -> f(m(k1)) else k2 -> v2 //original
k1 -> f(m(k1)) else k1 -> v2
k1 -> f(m(k2)) else k2 -> v2
k1 -> f(m(k2)) else k1 -> v2
k2 -> v2 else k1 -> f(m(k1))
k1 -> v2 else k1 -> f(m(k1))
k2 -> v2 else k1 -> f(m(k2))
k1 -> v2 else k1 -> f(m(k2))
... //v2 may also be a function from some key's value
Run Code Online (Sandbox Code Playgroud)
那么,为什么它不是标准功能呢?IMO,因为所有变体仍然可以实现为单行.如果你想要具有所有功能的库,可以实现为单行,你知道,它是Scalaz :).
PS如果你也想知道为什么没有"更新(d)if persist"功能 - 请参阅@Rex Kerr 这里的答案
Jea*_*art 13
您可以为此创建自己的功能:
def addOrUpdate[K, V](m: collection.mutable.Map[K, V], k: K, kv: (K, V),
f: V => V) {
m.get(k) match {
case Some(e) => m.update(k, f(e))
case None => m += kv
}
}
addOrUpdate(a, "k1", "k5" -> 200, (v: Int) => v + 5)
Run Code Online (Sandbox Code Playgroud)
小智 6
Scala 2.13 引入了updatedWith方法,这似乎是根据键的存在条件更新映射的最惯用的方法。
val a = Map(("k1" -> 1), ("k2" -> 5))
val a1 = a.updatedWith("k1") {
case Some(v) => Some(v + 5)
case None => Some(200)
}
println(a1) // Map(k1 -> 6, k2 -> 5)
Run Code Online (Sandbox Code Playgroud)
也可以使用它删除值:
val a2 = a.updatedWith("k2") {
case Some(5) => None
case v => v
}
println(a2) // Map(k1 -> 1)
Run Code Online (Sandbox Code Playgroud)
Scala 标准库参考的摘录:
def updatedWith[V1 >: V](key: K)(remappingFunction: (Option[V]) => Option[V1]): Map[K, V1]更新指定键及其当前可选映射值的映射(
Some如果有当前映射,None如果没有)。如果重映射函数返回
Some(v),则使用新值更新映射v。如果重映射函数返回None,则删除映射(如果最初不存在,则保持不存在)。如果函数本身抛出异常,则重新抛出异常,当前映射保持不变。