1

For an immutable Map,

val original = Map("A"->1, "B"->2)

I can either use

original.map { case (k, v) => (k, v + 1) }

Or

original.transform((_, v) => v + 1)

to transform the values.

But why map() method requires case pattern matching but transform() doesn't? Is it because of these methods are defined in different implicit types?


Someone has marked my question as a duplicate of another question [Difference between mapValues and transform in Map. It is not the same. I am asking Map.map not Map.mapValues. Also I am asking the different way of using the two methods.

CyberPlayerOne
  • 3,078
  • 5
  • 30
  • 51

3 Answers3

3

With map method you can change (don't want to use transform word here) whole Map converting it to another Map, List etc

val m = Map(1->"a")
m.map { case (k,v) => (k+1) -> (v + 1) } // Map(2 -> a1)
m.map { case (k,v) => k+v } // List(1a)

With transform method you can change only values considering their keys

m.transform { case (k, v) => v + 1 } // Map(1 -> a1)
Sergii Lagutin
  • 10,561
  • 1
  • 34
  • 43
1

The difference is in the function they receive. As you can see in the API

def transform[W, That](f: (K, V) ⇒ W)(implicit bf: CanBuildFrom[Map[K, V], (K, W), That]): That

def map[B](f: (A) ⇒ B): Map[B]

transform's function receives a tuple f: (K, V) ⇒ W while map's function receives a single value (which can obviously be a Tuple) f: (A) ⇒ B

So if you want to treat differently and in a easy-to-read way you should use the case word.

You can also do something like this, but is way less readeable:

original.map(r => (r._1, r._2+1))
SCouto
  • 7,808
  • 5
  • 32
  • 49
  • This is a wrong explanation of the difference: they both receive a tuple, so no difference here. – Dima Jan 29 '18 at 11:25
  • Are you sure it is wrong? It seems in the documentation and the original Scala codes, the map method's signature is indeed `def map[B](f: (A) ⇒ B): Map[B]` whose function parameter receives a single value. When I use IntelliJ IDEA, the auto-completion shows the function parameter receives a tuple not a single value. This is probably misleading? – CyberPlayerOne Jan 30 '18 at 03:09
  • @Tyler提督九门步军巡捕五营统领 A tuple is a single value, a single tuple. Transform is different, it receives two values individually instead of as a tuple. That's only the simplified signature of map, the full signature is `def map[B, That](f: ((K, V)) ⇒ B)(implicit bf: CanBuildFrom[Map[K, V], B, That]): That` Which makes it clear that the function passed in should have a tuple value containing the key and value as inputs. – puhlen Jan 30 '18 at 21:19
  • So `transform`'s parameter function takes two parameter inputs, which are not a single tuple. `map`'s parameter function takes a single parameter input, which is a tuple (single value). Now it makes more sense.. – CyberPlayerOne Jan 31 '18 at 04:08
1

Transform take a function that has two values as inputs, the first is the key and the second the value. Pattern matching is not needed since the two values are passed in individually.

On the other hand, the function passed to map takes in a single tuple containing the key and value of the element as an input. Pattern matching is used to break this tuple into it's components. You don't have to use pattern matching, but that would mean working with the tuple object instead of it's contents.

puhlen
  • 8,400
  • 1
  • 16
  • 31