我正试图了解与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 )
}
答案 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 questions和blog posts致力于它,因为与此混淆相关的问题,如果您感兴趣,值得一读在使用这种方法。
使用简明mapValues
语法获得稳定映射的一种方法是force
地图的基础view
实现:
val newMap = myMap.mapValues(_ + it.next).view.force //now stable!
您也可以拨打toSeq
然后再调用toMap
,但这会影响性能。
在当天结束时,使用常规map
或for
理解可能更简单:
//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的回答),如果您想使用/了解理解,那么这个方法就完全没问题了。