Scala函数获取地图,修改值并返回地图

时间:2015-04-22 10:05:12

标签: scala collections for-comprehension

我正试图了解与for有关的Scala Maps理解。我有以下代码,我的意图是打破键值对,对值执行某些操作并返回修改后的Map。我使用正确的功能还是应该使用别的东西?

val kvpair = Map("a" -> 1, "b" -> 2, "c" -> 3)

def multiplyValues(map: Map[Char, Int]) = {

          for {
              char <- map._1  
              value <- map._2 * 2
          } yield (char, value )
  }

4 个答案:

答案 0 :(得分:5)

Map中,方法mapValues传达了这一要求;例如,

kvpair.mapValues(_ * 2)

将地图中的每个值加倍。

答案 1 :(得分:3)

简单如下:

def multiplyValues(map: Map[Char, Int]) =
  for {
    (char,value) <- map
    modValue = value * 2
  } yield (char, modValue)

def multiplyValues(map: Map[Char, Int]) =
  for ((char,value) <- map) yield (char, value* 2)

甚至

def multiplyValues(map: Map[Char, Int]) = map mapValues (_ * 2)

答案 2 :(得分:1)

正如其他人在此处所述,您可能正在寻找的方法称为mapValues

val myMap = Map("one" -> 1, "two" -> 2)
val newMap = myMap.mapValues(_ + 1)  

println(newMap) //Map(one -> 2, two -> 3)

但是你必须非常小心这个方法,因为它的底层实现是一个视图,这意味着它被懒惰地评估。由于immutable.Map上的大多数其他方法行为不同,这可能会令人惊讶,混淆或导致错误。例如:

val it = Iterator.from(0)
val myMap = Map("one" -> 1, "two" -> 2)
val newMap = myMap.mapValues(_ + it.next)

println(newMap) //Map(one -> 3, two -> 5), as expected
//Try printing again, though:
println(newMap) //Map(one -> 5, two -> 7), I thought this map was immutable!

因此每次迭代地图时都会重新评估newMap中的值!这通过延迟地图的评估并在可能的情况下避免迭代来作为优化来完成。这可能是违反直觉的,这种方法甚至有several other questionsblog posts致力于它,因为与此混淆相关的问题,如果您感兴趣,值得一读在使用这种方法。

使用简明mapValues语法获得稳定映射的一种方法是force地图的基础view实现:

val newMap = myMap.mapValues(_ + it.next).view.force //now stable!

您也可以拨打toSeq然后再调用toMap,但这会影响性能。

在当天结束时,使用常规mapfor理解可能更简单:

//If you prefer "map":
myMap.map { case (key, value) => (key, value + 1) }
//If you prefer "for"
for { (key, value) <- map } yield (key, value + 1)

答案 3 :(得分:-2)

虽然还有其他(可能更优雅)的方法(请参阅@ elm的回答),如果您想使用/了解理解,那么这个方法就完全没问题了。