在scala.immutable.Map中更新多个值的惯用方法

时间:2014-02-24 20:41:21

标签: scala map idiomatic

我需要更新(检索并增加)绑定到地图中两个键的两个不同值。这两个键有时会重合。 我现在有以下代码:

// val map: Map[Int, Int]
// val key1, key2: Int
if (key1 == key2) {
  tailRecFunction(someArg, map 
    + Tuple2(key1, 2 + map.getOrElse(key1, 0)))
} else {
  tailRecFunction(someArg, map 
    + Tuple2(key1, 1 + map.getOrElse(key1, 0))
    + Tuple2(key2, 1 + map.getOrElse(key2, 0)))
}

如您所见,如果您在else时使用key1 == key2阻止,那么key1 == key2的值将错误地增加1而不是2 } ---第二个元组错误地更新原始值,而不是第一个元组应用的值 有更简洁的方式来写这个吗?

2 个答案:

答案 0 :(得分:5)

首先,您可以简化地图,以便在没有密钥时返回0

val map0 = Map.empty[Int, Int] withDefaultValue 0

然后,您可以安全地拨打map(key)而不是map.getOrElse(key, 0)

其次,您可以使用箭头关联语法来创建Tuple2个实例。即key -> value代替Tuple2(key, value)

第三,我根本不会介绍if ... then ... else。只需连续更新每个密钥的映射:

def addKey(map: Map[Int, Int], key: Int) = map + (key -> (map(key) + 1))

val map1 = addKey(map0, key1)
val map2 = addKey(map1, key2)
tailRecFunction(someArg, map2)

答案 1 :(得分:0)

另一个SO Answer建议使用Map(ScalaZ)的 Monoid 特征:

tailRecFunction(someArg, map |+| Map(key1 -> 1) |+| Map(key2 -> 1))

|+|运算符将对属于同一个键的值求和。