Difference between mapValues and transform in Map

前端 未结 3 488
甜味超标
甜味超标 2020-12-24 02:23

In Scala Map (see API) what is the difference in semantics and performance between mapValues and transform ?

For any given map

3条回答
  •  半阙折子戏
    2020-12-24 02:35

    collection.Map doesn't provide transform: it has a different signature for mutable and immutable Maps.

    $ scala
    Welcome to Scala version 2.11.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_11).
    Type in expressions to have them evaluated.
    Type :help for more information.
    
    scala> val im = Map('a -> 1, 'b -> 2, 'c -> 3)
    im: scala.collection.immutable.Map[Symbol,Int] = Map('a -> 1, 'b -> 2, 'c -> 3)
    
    scala> im.mapValues(_ * 7) eq im
    res0: Boolean = false
    
    scala> im.transform { case (k,v) => v*7 } eq im
    res2: Boolean = false
    
    scala> val mm = collection.mutable.Map('a -> 1, 'b -> 2, 'c -> 3)
    mm: scala.collection.mutable.Map[Symbol,Int] = Map('b -> 2, 'a -> 1, 'c -> 3)
    
    scala> mm.mapValues(_ * 7) eq mm
    res3: Boolean = false
    
    scala> mm.transform { case (k,v) => v*7 } eq mm
    res5: Boolean = true
    

    Mutable transform mutates in place:

    scala> mm.transform { case (k,v) => v*7 }
    res6: mm.type = Map('b -> 98, 'a -> 49, 'c -> 147)
    
    scala> mm.transform { case (k,v) => v*7 }
    res7: mm.type = Map('b -> 686, 'a -> 343, 'c -> 1029)
    

    So mutable transform doesn't change the type of the map:

    scala> im mapValues (_ => "hi")
    res12: scala.collection.immutable.Map[Symbol,String] = Map('a -> hi, 'b -> hi, 'c -> hi)
    
    scala> mm mapValues (_ => "hi")
    res13: scala.collection.Map[Symbol,String] = Map('b -> hi, 'a -> hi, 'c -> hi)
    
    scala> mm.transform { case (k,v) => "hi" }
    :9: error: type mismatch;
     found   : String("hi")
     required: Int
                  mm.transform { case (k,v) => "hi" }
                                               ^
    
    scala> im.transform { case (k,v) => "hi" }
    res15: scala.collection.immutable.Map[Symbol,String] = Map('a -> hi, 'b -> hi, 'c -> hi)
    

    ...as can happen when constructing a new map.

提交回复
热议问题