views:

258

answers:

1

In 2.7 I could do the following:

val lazyM: Map[_, _] = map.projection.mapElements(v => expCalc(v)) //MAP VIEW

I can't find a way of doing this in 2.8 and actually ending up with a map:

val m: Map[_, _] = map.view.map(kv => kv._1 -> expCalc(kv._2)).toMap //STRICT

This seems like a significant loss of functionality and therefore I assume it's hiding in the collection library somewhere. Anyone have any ideas?

Edit - stupidly I assumed that mapValues was exactly the same as the old mapElements

+4  A: 

Somewhat surprisingly, Map#mapValues produces a (transformed) view:

scala> Map(1 -> 2, 3 -> 4, 5 -> 6)
res0: scala.collection.immutable.Map[Int,Int] = Map((1,2), (3,4), (5,6))

scala> res0.mapValues { v => println("computing from " + v); v + 1 }
computing from 2
computing from 4
computing from 6
res1: scala.collection.immutable.Map[Int,Int] = Map((1,3), (3,5), (5,7))

scala> res1(1)
computing from 2
res2: Int = 3

scala> res1(5)
computing from 6
res3: Int = 7
RM
This is not exactly "lazy" (zero or one evaluations per key with those evaluations delayed as long as possible), it's more like "dynamic" in that the function supplied in the call to `mapValues` is evaluated *every time a key in the resulting Map view is retrieved*.
Randall Schulz
Yes, it's what I meant though. I shouldn't have used the word lazy
oxbow_lakes
I'd suggest saying "mapValues returns a view".
Seth Tisue
Good points on "lazy" being the wrong word.
RM